我想優化sql查詢。它在內部執行Hash Join,所以它要進行全表掃描以獲得結果。
alter session set "_hash_join_enabled" = false;
如果我使用上述命令,oracle會進行嵌套回圈,并且沒有全表掃描。
誰能給我建議一下這個的實時應用嗎?
uj5u.com熱心網友回復:
問題不在于全表掃描,而在于執行查詢的時間。優化器選擇了哈希連接和FTS,因為它認為它比嵌套回圈快。通常這是統計學的問題,或者是查詢的撰寫方式的問題。
如果你真的想通過這樣的提示來做,那么就像評論中所說的那樣,在陳述句級別使用它(例如,opt_param('_hash_join_enabled','false'),或者use_nl(把表名按照你想要的順序放在這里))。
uj5u.com熱心網友回復:
一般來說,任何以下劃線開頭的引數都是未記錄的引數。 在生產系統中設定任何未記錄的引數都是不明智的,除非Oracle支持部門明確告訴你這樣做。 這幾乎總是在他們確認你遇到了一個特定的錯誤,并幫助你確定最好的解決方法是設定一個無記載的引數之后。
為會話禁用散列連接意味著該會話的任何運行將不考慮使用散列連接。 至少,在你設定這樣的引數之前,你要分析該會話可能運行的每個查詢的計劃(很可能是你的應用程式可能運行的每個查詢),以確定它們當前是否正在使用哈希連接,以及如果它們使用其他連接,預期的性能影響是什么。 你還想在一個較低的環境中做一個完整的性能回歸測驗,以確定這個變化對應用程式的性能有什么影響。 對于一個系統來說,很少會有一些查詢能從使用哈希連接中受益。
如果問題是一個單一的查詢,那么在會話級別進行任何引數更改都可能是多余的。 在單個查詢層面上解決單個查詢的問題要有意義得多。 大多數情況下,當Oracle優化器選擇了一個糟糕的計劃時,問題在于你在一個或多個物件上的統計資料是不正確的。 這導致Oracle認為表掃描的效率比實際的要高,或者期望嵌套回圈連接的效率比實際的要低。 可能是統計資料已經過期,或者是某個特定的統計資料(即有傾斜資料的列上的直方圖)丟失。 如果你可以通過修復統計資料來解決這個問題,這就是首選方法。
如果你不能通過修復統計資料來解決這個問題,你可以考慮對查詢應用提示。 你可以在特定查詢中的提示中設定一個未記錄的引數,但最好是堅持使用記錄的提示。 而且,如果我試圖改變計劃,我希望提示告訴優化器你希望發生什么,比如use_nl提示,而不是告訴優化器什么不允許的提示。 如果你禁用了哈希連接,Oracle很可能會因為統計資料的變化或資料庫的升級而開始做合并連接而不是嵌套回圈連接。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/324982.html
標籤:
上一篇:我如何在單引號中傳遞變數?
