在Oracle查詢過程中,對那些連接了很多表的查詢,Oracle需要花費大量的時間來檢測連接這些表的適當順序。 Oracle查詢中表的連接順序成為了我們需要思考的問題。
評估表的連接順序
在SQL語句的准備過程中,花費最多的步驟是生成執行計劃,特別是處理有多個表連接的查詢。當Oracle評估表的連接順序時,它必須考慮到表之間所有可能的連接。例如:六個表的之間連接有720(6的階乘,或6 * 5 * 4 * 3 * 2 * 1 = 720)種可能的連接線路。
當一個Oracle查詢中含有超過10個表的連接時,排列的問題將變得更為顯著。對於15個表之間的連接,需要評估的可能查詢排列將超過1萬億
(准確的數字是1,307,674,368,000)種。
使用optimizer_search_limit參數來設定限制
通過使用optimizer_search_limit參數,你能夠指定被優化器用來評估的最大的連接組合數量。使用這個參數,我們將能夠防止優化器
消耗不定數量的時間來評估所有可能的連接組合。如果在Oracle查詢中表的數目小於optimizer_search_limit的值,優化器將檢查所有可能的
連接組合。
例如:有五個表連接的查詢將有120(5! = 5 * 4 * 3 * 2 * 1 = 120)種可能的連接組合,因此如果optimizer_search_limit等於5
(默認值),則優化器將評估所有的120種可能。optimizer_search_limit參數也控制著調用帶星號的連接提示的閥值。當查詢中的表的
數目比optimizer_search_limit小時,帶星號的提示將被優先考慮。
另一個工具:參數optimizer_max_permutations
初始化參數optimizer_max_permutations定義了優化器所考慮組合數目的上限,且依賴於初始參數optimizer_search_limit。
optimizer_max_permutations的默認值是80,000。
參數optimizer_search_limit和optimizer_max_permutations一起來確定優化器所考慮的組合數目的上限:除非(表或組合數目)
超過參數optimizer_search_limit 或者 optimizer_max_permutations設定的值,否則優化器將生成所有可能的連接組合。一旦優
化器停止評估表的連接組合,它將選擇成本最低的組合。
使用ordered提示指定連接順序
你能夠設定優化器所執行的評估數目的上限。但是即使采用有很高價值的排列評估,我們仍然擁有使優化器可以盡早地放棄復雜的查詢
的重要機會。回想一下含有15個連接查詢的例子,它將有超過1萬億種的連接組合。如果優化器在評估了80,000個組合後停止,那麼它才
僅僅評估了0.000006%的可能組合,而且或許還沒有為這個巨大的查詢找到最佳的連接順序。
在Oracle SQL中解決此問題的最好的方法是手工指定表的連接順序。為了盡快創建最小的解決方案集,這裡所遵循的規則是將表結合起
來,通常優先使用限制最嚴格的WHERE子句來連接表。