Mysql大数据量分页查询优化
今天遇到了一个列表分页查询很慢的接口
1. 分析列表查询语句
列表查询语句关联了大约5张表,最后sql打印了limit 0,20
将sql放到数据库执行,500ms,语句分析索引全部命中
所以慢这里并不是列表查询慢
2. 分析count(*)语句
打印sql日志,可以看到count(*)的执行耗时达到了18s
count()执行原理,这里可以参考 count(*)
存在非聚集索引的count()会比只有聚集索引的结果快。这里是因为聚集索引的叶子节点包含了完整数据,访问的页较多,即磁盘I/O较多
当然我这里不是这个原因,这里count() 关联了多张表,多张表关联查询会导致count()变慢(具体原因待深究,实验可得这个结论)
3. 优化count(*)
因为结果都是一一对一应,这里我们单独写count(*)语句(mybatis使用分页插件,可以增加一个 id_COUNT的描述,总页数会走这个sql)
最后优化的sql为:
select count(*) from a
<if test= "queryB != null">
inner join b on a.id = b.aId
</if>
这样可以大大优化count(*)的执行时间
4. 分页越往后越慢
可以参考下面sql的写法
select * from orders_history where type=8 and
id>=(select id from orders_history where type=8 limit 100000,1)
limit 100;