一 什么是limit分頁問題
limit 20 這樣的語句。僅僅掃描前30行,select* from table limit 0,10掃描滿足條件的10行,返回10行,但當limit 866613,20的時候數據讀取就很慢,limit 866613,20的意思掃描滿足條件的866633行,扔掉前面的866613行,返回最后的20行,可想而知這時會很慢,如下圖,達到37.44秒之久。

二 怎么解決
利用表的覆蓋索引來加速分頁查詢
我們都知道,利用了索引查詢的語句中如果只包含了那個索引列(覆蓋索引),那么這種情況會查詢很快。
因為利用索引查找有優化算法,且數據就在查詢索引上面,不用再去找相關的數據地址了,這樣節省了很多時間。
另外Mysql中也有相關的索引緩存,在並發高的時候利用緩存就效果更好了。
在我們的例子中,我們知道id字段是主鍵,自然就包含了默認的主鍵索引。
這次我們之間查詢(利用覆蓋索引,只包含id列),如下:

查詢時間為0.2秒,相對於查詢了所有列的37.44秒,提升100多倍的速度。
那么如果我們也要查詢所有列,有兩種方法,
- 方法1:子查詢,id>=的形式:

查詢時間為0.2秒,簡直是一個質的飛躍啊。
- 方法2:利用join

效果也差不多查詢時間也很短。
三 子查詢和關聯查詢性能對比
上面兩個一個是子查詢,一個是關聯查詢,那么這兩種方案的查詢性能哪一個更好呢?
- 子查詢:把內層查詢結果當作外層查詢的比較條件,使用 IN( ) 函數、EXISTS 運算符等,示例如下:
select goods_id,goods_name from goods where goods_id = (select max(goods_id) from goods);
執行子查詢時,MYSQL需要創建臨時表,查詢完畢后再刪除這些臨時表,所以,子查詢的速度會受到一定的影響,這里多了一個創建和銷毀臨時表的過程。
- 連接查詢(JOIN)連接查詢不需要建立臨時表,因此其速度比子查詢快。另外注意:能過濾先過濾,過濾好了再鏈接
