MySQL查询时当offset较大时查询效率低

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012314976/article/details/73857169

正文

数据库有中1千万条数据,如下所示:

mysql> select count(*) from score;
+----------+
| count(*) |
+----------+
| 10000000 |
+----------+
1 row in set (1.89 sec)

mysql> select * from score limit 0,5;
+----+------+
| id | num  |
+----+------+
|  1 |  695 |
|  2 | 3635 |
|  3 | 7766 |
|  4 | 4574 |
|  5 |  134 |
+----+------+
5 rows in set (0.00 sec)

mysql> select * from score order by id desc limit 0,5;
+----------+------+
| id       | num  |
+----------+------+
| 10000000 | 1230 |
|  9999999 | 4717 |
|  9999998 | 4719 |
|  9999997 | 3636 |
|  9999996 | 9254 |
+----------+------+
5 rows in set (0.00 sec)

做分页查询时,当offset较小时,查询效率很高;但是当offset较大时,查询效率很容易达到秒级。如下所示:

mysql> select * from score limit 0,5;
+----+------+
| id | num  |
+----+------+
|  1 |  695 |
|  2 | 3635 |
|  3 | 7766 |
|  4 | 4574 |
|  5 |  134 |
+----+------+
5 rows in set (0.00 sec)

mysql> select * from score limit 9000000,5;
+---------+------+
| id      | num  |
+---------+------+
| 9000001 |  507 |
| 9000002 | 5379 |
| 9000003 | 3095 |
| 9000004 | 1925 |
| 9000005 | 1308 |
+---------+------+
5 rows in set (2.68 sec)

网上能找到的优化方法主要有两种:

一种是,将select * from score limit 9000000,5改写为select * from score as a inner join (select id from score limit 9000000,5) as b on a.id=b.id;,先查询出偏移后的id,然后再取出对应的数据,个人感觉这种优化程度还是不够好。不过当表中的字段较多时,应该会有较大的提升。

第二种是,将select * from score limit 9000000,5改写为select * from score where id>=9000000 limit 0,5;,这样能做到和查询前5条数据基本一样的效果。但是不足是需要记录上一页最后一个id的值。

以上两种情况可以根据实际场景选择。

参考

猜你喜欢

转载自blog.csdn.net/u012314976/article/details/73857169