Sql-Server

隱式轉換導致部分時間出錯

  • December 11, 2019

在過去的一天左右,我一直在為這個問題摸不著頭腦——我只是不明白為什麼一個程序在一個環境中工作,但由於轉換錯誤(相同的數據,相同的程式碼)而在另一個環境中失敗。

工作伺服器的(大幅縮減版本)計劃在這裡:https ://www.brentozar.com/pastetheplan/?id=B1jZWTfOf

(這似乎不起作用,所以我在這裡將計劃 XML 上傳到 pastebin:https ://pastebin.com/47Q6nniw )

導致問題的相關列的一些背景知識:

propertyInst 表包含一個名為 ValueStr 的列,它是一個 nvarchar 數據類型。GeneralLedgerCode 表具有數據類型 int 的列 id。我們的開發人員正在嘗試在兩個表之間進行連接。ValueStr 列包含文本數據、XML 數據、int 數據、十進制數據等。當然,我們決定添加一個函式來確保只解析整數 (ISNUMERIC(ValueStr) = 1)。我們沒有意識到的是,這也會嘗試轉換任何十進制值 - 這會導致性質生成中的轉換錯誤:

將 nvarchar 值“0.1”轉換為數據類型 int 時轉換失敗。

我的問題是,鑑於 propertyInst 表的表掃描將獲取包括小數在內的所有數值,為什麼標量運算符中的隱式轉換不會因相同的轉換錯誤而失敗?ISNUMERIC 查詢的輸出返回其中一些小數。我根本看不到附加的計劃是如何運作的。

隱式轉換運算符是否永遠不會完全失敗,轉換錯誤是否來自雜湊匹配運算符中的探測殘差?話又說回來,當隱式轉換失敗時,這個值怎麼能傳給操作員呢?

作為一個小小的幫助,計劃圖像在這裡,我詢問的計算標量被圈起來了。

計劃

此外,我可以看到沒有針對標量運算符記錄的實際行 - 這是否意味著引擎決定在執行時由於轉換錯誤而不使用該特定運算符?

計劃2

任何幫助,將不勝感激。

計算標量運算符的計算延遲到實際使用時(節點 ID = 1 的探測殘差),並且對您來說可能失敗的行被先前的雜湊匹配(節點 ID = 3)過濾掉。

查看Paul White 的Compute Scalars, Expressions and Execution Plan Performance了解更多資訊。

執行計劃中沒有跡象表明表達式的評估被推遲,或者何時(在哪個節點)實際評估了它。您通常可以使用CASE(附帶評估順序保證)和/或TRY_CONVERT.

相關微軟回饋:SQL Server 不應引發不合邏輯的錯誤

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