正文
數據庫有中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的值。
以上兩種情況可以根據實際場景選擇。