MySQL查詢時當offset較大時查詢效率低

正文

數據庫有中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的值。

以上兩種情況可以根據實際場景選擇。

參考

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章