Sql-Server

觸發此警告的原因:表達式中的類型轉換可能會影響查詢計劃選擇中的“CardinalityEstimate”

  • August 31, 2019

使用 SQL Server 2016,我試圖了解為什麼在執行此 T-SQL 語句時收到此警告(我選擇 table 變數以方便測試。這發生在具有int類型列的 DB 表中):

declare @test as table(
   col1 int
)

insert into @test (col1)
values(30500600)

select LEFT(test.col1, 2)
from @test as test

30按預期返回,但在檢查執行計劃時,我看到一條警告SELECT語句,內容如下:

表達式中的類型轉換 (CONVERT_IMPLICIT(varchar(12),

$$ test $$.$$ col1 $$,0)) 可能會影響查詢計劃選擇中的“CardinalityEstimate”

如果我在沒有從表中拉出的情況下執行相同的操作:

select LEFT(30500600, 2)

30按預期返回,執行計劃中沒有警告。

這兩個語句都應該LEFT()int類型上執行,所以我不明白為什麼一個返回警告而另一個沒有。這裡發生了什麼?

編輯:

我嘗試將col1數據類型聲明更改為varchar並清除錯誤。但這仍然不能向我解釋為什麼select LEFT(30500600, 2)如果我將 anint直接傳遞給LEFT()函式,它本身不會引起警告。

我嘗試castvarchar原始查詢中:LEFT(cast(test.col1 as varchar(12)), 2)返回相同的警告。

可能重複

連結的重複項表明計算列是該使用者的問題。我的範例中沒有計算列,所以這不是問題。這將我引向關於使用函式隱式轉換為字元串類型的答案的第二部分,該CONCAT函式也相同LEFT。在我上面編輯的第二段中,我曾經CAST明確轉換為,varchar所以我認為不會發生轉換?我顯然在這裡遺漏了一些東西。

此查詢中沒有“類型轉換/基數估計”警告的原因:

SELECT LEFT(30500600, 2);

…是因為沒有基數估計。 它是一個常量表達式,被傳遞給確定性函式——保證只返回一個“行”。我認為解釋就這麼簡單,因為警告更多的是關於潛在的基數問題(而不僅僅是類型轉換的簡單存在)。

如果我得到該語句的估計執行計劃,它只是一個“選擇不查詢”元素:

<?xml version="1.0" encoding="utf-16"?>
<ShowPlanXML xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Version="1.518" Build="13.0.5081.1" xmlns="http://schemas.microsoft.com/sqlserver/2004/07/showplan">
 <BatchSequence>
   <Batch>
     <Statements>
       <StmtSimple StatementCompId="1" StatementId="1" StatementText="select LEFT(30500600, 2)" StatementType="SELECT WITHOUT QUERY" RetrievedFromCache="false" />
     </Statements>
   </Batch>
 </BatchSequence>
</ShowPlanXML>

對於它的價值,即使是表變數版本也不會在 SQL Server 2017中顯示警告(因為當轉換不可能影響基數估計時,它確實是一個毫無意義的警告 - 如您的範例所示)。

需要明確的是,這個警告並不總是毫無意義的。舉個例子:

SELECT message_id 
INTO #SomeNumbers
from sys.messages;

SELECT * 
FROM #SomeNumbers
WHERE LEFT(message_id, 2) = '50';

這會將 280,192 行放入臨時表中。SELECT 查詢有這個警告,警告是合法的。SQL Server 估計有 28,019.2 個匹配行(佔表的 10%),而實際上只有 2,156 個匹配行(<1% 的表)。

關於您將此輸入轉換為LEFT函式的範例,請注意警告已從略微更改CONVERT_IMPLICIT為 just CONVERT

表達式中的類型轉換 (CONVERT(varchar(12),

$$ test $$.$$ col1 $$,0)) 可能會影響查詢計劃選擇中的“CardinalityEstimate”

因此,您只是用顯式轉換替換隱式轉換,這仍然需要警告。

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