1. 程式人生 > >MySQL order by id 也會有不走索引

MySQL order by id 也會有不走索引

我在網上找了半天一直疑問著, 不知為什麼??

但答案找到了, 呵呵。。讓我心裡解開了

<!-->

query result(1 records)

count(*)
993098


下面我們 來一步一步看看下面的這條語句:
explain select sql_no_cache * from t_page_sample order by id asc limit 900001,20; 
<!-->
<!-->

query result(1 records)

id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t_page_sample ALL (NULL) (NULL) (NULL) (NULL) 993098 Using filesort


從 上面可以看出,她沒有用到任何索引,掃描的行數為993098,而且用到了排序!

select sql_no_cache * from t_page_sample order by id asc limit 900001,20; 

(20 row(s)returned) 

(4688 ms taken)

 

那麼我們怎麼優化這條語句呢?
首先,我們想到的是索引。 在這條語句中,只有ID可能能用到索引,那麼我們給優化器加一個暗示條件,讓他用到索引。


select sql_no_cache * from t_page_sample force index (primary)

 order by id asc limit 900001,20; 

(20 row(s)returned) 
(9239 ms taken) 

沒想到用的時間竟然比不加索引還長。 看來這條路好像走不通了。
我們嘗試著變化下語句如下: 
select * from t_page_sample 
where id between 
         (select sql_no_cache id from t_page_sample order by id asc limit 900001,1)
         and 
         (select sql_no_cache id from t_page_sample order by id asc limit 900020,1);

 

(20 row(s)returned)
 
(625 ms taken) 
哇,這個很不錯,足足縮短了將近15倍! 
那麼還有優化的空間嗎? 
我 們再次變化語句: 
select * from t_page_sample 
where id >= ( select sql_no_cache id from t_page_sample order by id asc limit 900001,1) 

limit 20; 

(20 row(s)returned) 
(406 ms taken) 

時間上又比上次的語句縮短了1/3。可喜可賀。