整体思路为:先查询出全表记录数,然后分段查询。
项目中需要对数据库的一张表做全表查询,开发测试阶段数据量小,使用
java
1 | select count(*) from 'tableName' |
查询到时没什么问题,可是到项目代码review的时候发现这么写有很大的问题。
虽然该条SQL语句一定会查到表记录数量,但如果表中数据很多的时候,该条语句执行时间会较长,例如某司有一张表内数据1亿条,执行时间47秒,这在项目真线环境是很可怕的。因为这一慢SQL查询会引起其他SQL的执行效率,严重的引发链式反应,大量消耗服务器资源;
因此还有一种写法为:
java
1 | select count(字段名) from 'tableName' |
这种写法执行速度较先前那种方式更快;但是也有一个小问题要注意,count(字段名)查询的是该字段不为null值的记录总量。它有可能和count(*)相等,也可能不等,使用时要慎重;
假设:
1、数据库表主键ID是自增的;
2、该表不会删除数据,或只从头部删除数据(保证数据的完成性);
此时使用如下语句会大大加快表记录数量;
java
1 | select (max(id) - min(id) + 1) as total from 'tableName' |
如果确定数据库表一定不会删除数据,也可以简化为:
java
1 | select max(id) as total from 'tableName' |
此时利用了表主键自增长的特性;同样1亿条数据,只需要不到1秒的查询时间,效果很明显。
巧合的是我们项目中需要完全满足这种条件,在使用” select max(id) as total from ‘tableName’ ”查询出表总记录的情况下,我们对全表读取操作做了分段处理,处理思路如下:
java
1 | Long total -> ( select max(id) as total from 'tableName' ); |