Sql性能優化–Explain命令後續之USE INDEX
最近在開發一個推廣渠道自行查詢訂單的功能,因爲幾年下來,平臺的訂單量也有百萬級別了,發現雖然在用渠道ID字段查詢時,雖然渠道ID加了索引,但仍然需要13秒左右才能拿到查詢結果,我的訂單表結構如下(下面只列出了跟本主題相關的列):
id(主鍵) | channelId(渠道id,索引列) | createTime(創建時間,索引列) |
---|
,我的SQL是這樣的:
SELECT id,channelid,createTime FROM
order
WHERE channelId=’1’ ORDER BY createTime DESC LIMIT 20
我的感覺以現有數據庫服務器的配置,這個數據量應該不至於這麼慢的,於是用Explain命令分析了一下,結果如下圖:
id | table | Type | Possibole_keys | key | Extra |
---|---|---|---|---|---|
1 | Order | Index | channelId | createTime | Using where |
Mysql是用了createTime作爲查詢的索引,跟預想的情況不大一樣,分析了一下原因,可能是Mysql默認認爲排序列索引的優先級比條件裏的高吧,又或者因爲createTime字段值本身更分散一些,所以Mysql優先使用了這列作爲查詢索引。
從這個場景可以看出實際上任何一下數據庫的查詢分析器都不是萬能的,雖然本身它們在算法上都有做了優化,會嘗試去找到最佳的篩選方式,但不是所有的情況下都管用,程序員必須帶着辯證的思維方式去看待,遇到問題時要認真分析而不是盲目地相信數據庫一定會做出最好的選擇。因爲索引的目的是爲了快速縮小查找範圍,但在這條SQL裏,創建時間僅用來排序,是它來做索引是無法快速縮小範圍的,而用渠道id來做索引則能迅速地縮小範圍,所以嘗試使用了USE INDEX(channelId)方法指定使用索引,果然查詢速度有了20倍的提升(由原來的13.45秒提升到0.58秒),SQL性能優化確實是無止境的,永遠都有提升空間。
附上加了USE INDEX指令的SQL:
SELECT id,channelid,createTime FROM
order
USE INDEX(channelId) WHERE channelId=’1’ ORDER BY createTime DESC LIMIT 20