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)
(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。可喜可賀。