查詢最佳化工具的工作是為執行 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 個或更多表格的查詢可能很容易需要數小時甚至數天的時間才能編譯。同時,如果使用optimizer_search_depth
等於 3 或 4 來編譯,最佳化工具可能會在不到一分鐘的時間內編譯相同的查詢。如果您不確定optimizer_search_depth
的合理值是多少,則可以將此變數設定為 0,讓最佳化工具自動判斷值。