Sql-Server

更改優化器使用索引的計劃

  • July 21, 2017

當我按如下方式執行查詢時,執行時間不到 1 秒。

SELECT @tenor_from =CONVERT(DATETIME,MIN(spc.maturity_date),103)  
   FROM source_price_curve spc   
   WHERE spc.as_of_date >= @as_of_date_from

它利用表中基於到期日期列的非聚集索引。然後我在連接中添加了一個臨時表,如下所示

SELECT @tenor_from =CONVERT(DATETIME,MIN(spc.maturity_date),103)  
FROM source_price_curve spc  
INNER JOIN #source_price_curve_list spcl
   ON spc.source_curve_def_id  = spcl.price_curve_id  
WHERE spc.as_of_date >= @as_of_date_from

在這種情況下,也看到使用了相同的索引(除非重新編譯或通過提示強制使用新索引),但是,性能顯著下降(至 12 秒),這是通過使用交叉應用條件解決的(如 Paul 所建議的)。

我擔心的是,有沒有辦法改變優化器的計劃或讓優化器自動選擇一個新的索引,用於新查詢的連接或過濾條件?(據我所知,優化器使用相同的索引,除非重新編譯或強制使用新索引作為提示。)

提前致謝。

您的兩個查詢是不同的,並且具有不同的執行計劃。雖然他們可能都使用特定的索引,但該索引是獨立選擇的。查詢執行的基本任務是不同的(一個有一個表,一個使用兩個),因此它們不可能使用相同的計劃。

一旦優化器確定了給定查詢的計劃,它將按照您的指示重用該計劃。但是,查詢必須相同。即使更改硬編碼值通常也會導致生成新計劃(請參閱產品文件中的參數和執行計劃重用)。

作為一般規則,有時好的但有時不好的計劃通常是由於其中包含變數的查詢,或者在查詢中使用傳入參數的過程和函式中的查詢。

幫助優化器做出最佳選擇的最佳方法是確保您的統計資訊是最新的。當優化器對將找到的行數做出良好估計時,它的計劃更有可能是好的。

優化器拒絕選擇最佳查詢的情況相對較少;在這些罕見的情況下,您可以使用各種查詢提示來(例如)強制使用特定索引。

也就是說,通常應該非常謹慎地使用提示,尤其是在重複程式碼中(腳本定期執行、應用程序等)。使用這樣的查詢提示會阻止優化器考慮某些選項,並且隨著數據的變化,今天最好的選項可能不是一個月或一年內最好的。你今天“完美計劃”的查詢可能會成為下個月、下週甚至明天的嚴重瓶頸。除了查詢提示之外,您還可以使用計劃指南(我不知道它們是否存在)。

大多數情況下,最好的解決方案是調整查詢,以便選擇更好的索引,或者減少工作量。這有時可能感覺像是找到一種方法來“欺騙”優化器做你想做的事。但是,這實際上是向優化器解釋您想要做得更好的問題。如果你說一門外語,你要求去洗手間上廁所,但你實際上說的是“我需要用你的浴缸”,如果你說話的人有錯去給你拿毛巾而不是直接帶你去最近的廁所?

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