Sql-Server

隱式轉換:什麼時候會嚴重損害性能?

  • March 17, 2021

我知道當數據類型相同時它是好的,當它們不同時它會損害性能。

但有時它似乎影響很小,修復它基本上是浪費時間。其他時候,它會產生巨大的影響,並且性能會變得更好。

當然有很多場景,例如插入選擇,其中選擇的數據類型與插入列不同但兼容。或者它可能在連接謂詞上。

隱式轉換在哪裡傷害最大?

此外,當長度不匹配時,似乎也可以進行隱式轉換,例如將 varchar(10) 與 varchar(20) 連接。當我們只處理列的長度而不是它們的類型時,這些場景有多大意義?

基本上我想知道我什麼時候應該擔心執行計劃中的計算標量運算符。我怎麼知道刪除它是否會產生重大影響?

有兩個主要問題會導致隱式(或顯式)轉換對查詢計劃產生重大影響:

**問題的主要點是連接或過濾謂詞,或者排序或分組,在轉換的列上。另請注意,這同樣適用於在這種上下文中使用的列上的任何函式。**剛剛選擇的列的影響要小得多。

這意味著首先編譯器不能使用索引查找來獲取數據,也不能依賴轉換輸出以正確的順序進行合併連接流聚合等操作。

這一點比某些人意識到的要陰險得多。通過一些轉換,例如intto float,編譯器將這些轉換理解為保持順序。但是諸如varcharto之類的轉換nvarchar沒有這樣的語義。

因此,當連接 sayvarcharnvarcharcolumn 時,有必要確定要查找的表是哪個表,因此通常顯式轉換更好。

第二個問題是比較知名的:**沒有統計數據。**編譯器不了解轉換的結果意味著什麼,因此它不能使用統計數據來確定估計的行數和密度。這通常會影響整個計劃,並且通常會在計劃越深入時產生更大的差異。


如果轉換或函式僅在 select 中(並且不在查詢的外部進行謂詞),那麼即使出現相同的警告,影響也會小得多。在這種情況下,通常轉換將在查詢輸出行之前發生,它通常不會影響任何查詢計劃。

可以產生影響的兩種情況select是:

  • 轉換為更大的類型,例如 LOBmax類型。確保盡可能晚地進行轉換是有益的。
  • 非常複雜的嵌套字元串函式,它們通過CROSS APPLY. 在這裡,情況正好相反:早點進行計算,並防止編譯器嘗試將整個事物嵌套為一個大的Compute ScalarOUTER APPLY是你的朋友,它似乎給出了優化圍欄的效果。

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