天天看點

MySQL · 捉蟲動态 · 5.6中ORDER BY + LIMIT 錯選執行計劃

從select語句中可以看出,同樣的語句,使用同樣的index,但使用了force index之後選擇的執行計劃不一樣。當然如果資料量大的話,實際的執行性能也會差别很大。使用range scan顯然要優于index scan的全掃描。

另外此bug引發的另一個問題是,由于使用了limit語句,導緻選擇的index不是最優的index。

使用如下指令打開optimizer trace

執行上面的查詢語句,可以看到optimizer trace的輸出結果如下,請注意裡面重點部位的注釋(以’//’開頭部分):

這裡顯示的是optimizer在執行優化器的第四個階段,plan refinement的時候,最後選擇了index scan。是以我們可以大緻确定錯誤發生的地方。另外有問題的query帶有limit,是以基本可以确定問題發生在了make_join_select函數中。

make_join_select函數中有下面一段邏輯:

解決方式是需要将原來已經選好的range scan與用來進行排序的索引掃描代價進行比較,比較哪種掃描方式對于增加order by操作後的代價更低,進而選擇一個代價最優的掃描方式。下面是一個相關的patch。

可以看到最終效果是:

繼續閱讀