查詢最佳化工具的任務是找出執行 SQL 查詢的最佳計畫。由於「好」計畫和「壞」計畫在效能上的差異可能達到數個數量級(也就是說,秒與小時甚至天數的差異),因此大多數查詢最佳化工具,包括 MySQL 的查詢最佳化工具,都會在所有可能的查詢評估計畫中執行或多或少的詳盡搜尋,以找出最佳計畫。對於聯結查詢,MySQL 最佳化工具所調查的可能計畫數量會隨著查詢中參考的資料表數量呈指數成長。對於少量資料表(通常少於 7 到 10 個),這不是問題。但是,當提交較大的查詢時,花費在查詢最佳化的時間很容易成為伺服器效能的主要瓶頸。
更彈性的查詢最佳化方法讓使用者能夠控制最佳化工具在搜尋最佳查詢評估計畫時的詳盡程度。一般概念是,最佳化工具調查的計畫越少,編譯查詢所花費的時間就越少。另一方面,由於最佳化工具會略過某些計畫,因此可能無法找到最佳計畫。
可以使用兩個系統變數來控制最佳化工具在評估計畫數量方面的行為
optimizer_prune_level
變數會告知最佳化工具根據每個資料表存取的列數估計值來略過某些計畫。我們的經驗顯示,這種「有根據的猜測」很少會錯過最佳計畫,而且可能會大幅縮短查詢編譯時間。這就是為什麼預設會開啟此選項 (optimizer_prune_level=1
)。但是,如果您認為最佳化工具錯過了更好的查詢計畫,則可以關閉此選項 (optimizer_prune_level=0
),但可能會導致查詢編譯時間變長。請注意,即使使用此啟發式方法,最佳化工具仍然會探索大約指數數量的計畫。optimizer_search_depth
變數會告知最佳化工具應查看每個不完整計畫的「未來」多遠,以評估是否應進一步擴展。較小的optimizer_search_depth
值可能會導致查詢編譯時間縮短數個數量級。例如,如果optimizer_search_depth
接近查詢中的資料表數量,則具有 12、13 個或更多資料表的查詢可能很容易需要數小時甚至數天的時間才能編譯。同時,如果使用等於 3 或 4 的optimizer_search_depth
進行編譯,則最佳化工具可能會在不到一分鐘的時間內編譯相同的查詢。如果您不確定optimizer_search_depth
的合理值為何,則可以將此變數設定為 0,以告知最佳化工具自動判斷該值。