在实际场景中会遇到这样的一种情况:数据量很大,而且还要分页查询,如果数据量达到百万级别之后,性能会急剧下降,导致查询时间很长,甚至是超时。接下来我总结了两种常用的优化方案,仅供参考。但是需要注意的是有个前提:主键id是递增且数据有序。
1:使用子查询优化
这种方式先定位偏移位置的 id,然后往后查询,这种方式适用于 id 递增的情况。sql如下图所示:
1 SELECT
2 *
3 FROM
4 orders_history
5 WHERE
6 type = 8
7 AND id >= ( SELECT id FROM orders_history WHERE type = 8 LIMIT 100000, 1 )
8 LIMIT 100;
2:使用id限定优化
这种方式假设数据表的id是连续递增的,则我们根据查询的页数和查询的记录数可以算出查询的id的范围,可以使用id between and 来查询。sql如下图所示:
1 SELECT
2 *
3 FROM
4 orders_history
5 WHERE
6 type = 2
7 AND id BETWEEN 1000000
8 AND 1000100
9 LIMIT 100;
还可以有另外一种写法,sql如下图所示:
select * from orders_history where id >= 1000001 limit 100;
总结:这种查询方案的前提条件已经说过了,主键递增且数据有序。其实就是利用B+树的原理进行的,因为在Innodb存储引擎中,数据是通过B+树进行存储,叶子节点存储的是主键id,另外子查询中也用到了覆盖索引。一般查询条件排序条件为按照主键id递增,或者是递减,查询偏移起始位置是经过计算之后,带入到sql中的。如果数据量实在是太大了,如果达到千万级别的话,哈哈哈,我建议还是使用分库分表组件吧,比如Apache ShardingSphere、MyCat等开源组件。