Sql-Server

如何使用合併提示來隔離 SQL Server 中的複雜查詢

  • February 10, 2013

我可以理解,如果我加入“單獨快速”的單個查詢,則組合可能會變慢,因為預設執行計劃可能不是最佳的。但是,當我知道一個查詢的行數非常少時,我認為我應該能夠使用提示來控制連接。

select cj.a, cv.b
 from (select distinct a from complexJoin) cj -- 2 rows
inner loop join complexView cv
   on cj.a = cv.a
order by cj.a, cv.b

如果 cj <1s 並且 cv <1s 期望這是 <~2s 但使用任何提示(合併/散列/循環)通常 > 1 分鐘。

我還嘗試使用 CROSS APPLY,因為文件聲稱內部選擇對每個外部行只執行一次。該查詢比手動執行兩次內部查詢要長約 100 倍,所以也許我不理解文件。

select cj.a, cv.b
 from (select distinct a from complexJoin) cj -- 2 rows
cross apply (select * from complexView 
              where a = cj.a) cv
order by cj.a, cv.b

如果我用“cj”的結果填充一個臨時表,然後加入 with_no_hint 或使用交叉應用它很快,但我真的必須求助嗎?如果我使用臨時表並嘗試“任何”連接提示(循環/合併/雜湊),它會很慢,所以這可能是一個關鍵點。

我不相信需要深入查詢計劃的深度(兩者都是複雜的開始)來解決這種類型的問題:我只想保證隔離而不求助於臨時表——這真的不可能嗎?

如果您使用多語句 UDF,那麼您的內部選擇對於每個外部行只執行一次。多語句 UDF 被視為黑盒:執行計劃現在將顯示對複雜視圖中使用的對象的訪問。

另一方面,子查詢和/或內聯 UDF 會被優化器展平。在這種情況下,執行計劃將包括對複雜視圖中使用的對象的訪問。

優化器的大部分決策基於表的統計資訊。如果它們不是最新的,那麼 SQL 就不是一個好的選擇。每當您看到查詢的不良行為時,當您知道所涉及的行數與表的整體大小相比非常少時,您應該做的第一件事是確保統計資訊是最新的。這很快就完成了。通常的方法是重新索引表,但您可以使用專門更新統計資訊的命令獲得類似的結果。指定提示實際上幫助我處理過的查詢的次數非常少。

引用自:https://dba.stackexchange.com/questions/19297