簡體   English   中英

SQL 服務器 LEFT OUTER JOIN 到沒有參數的子查詢 - 嵌套循環加入?

[英]SQL Server LEFT OUTER JOIN to sub query without parameter - Nested Loops Join?

我有一個連接到子查詢的查詢。 當索引的 nvarchar 列作為字符串文字傳入時,性能會下降。 但是,當我傳入與參數相同的值時,執行計划會發生巨大變化,並且查詢會快速執行。 我為命名道歉。

在下面的情況下, myStringColumn被索引並且表有數百萬行。

這個不好:

SELECT myColumn from myTable1 LEFT OUTER JOIN
        (SELECT myColumn2 from myTable2
         WHERE myStringColumn = 'myFilter') ON...

這個不錯:

Declare @myParameter as nvarchar = N'myFilter'
SELECT myColumn from myTable1 LEFT OUTER JOIN
        (SELECT myColumn2 from myTable2
         WHERE myStringColumn = @myParameter) ON...

我不明白的是為什么第二個的表現要好得多。 據我所知,這是因為計划中的嵌套循環加入在第二個查詢中要好得多,但我不明白為什么。 我的猜測是,由於某種原因,SQL 服務器必須在第一次每次迭代中循環更多行,但我不知道為什么只更改為參數而不是字符串文字會產生如此大的影響。

問題:為什么第二個查詢比第一個更好? SQL 服務器在做什么使第一個慢得多?

謝謝你。

不同之處在於,當您聲明參數時,您使用 N 前綴正確執行它並將變量聲明為N varchar,與您的列相同。 當您執行 WHERE 時 - 您沒有添加 N 前綴,因此在內部創建了varchar變量,如果您執行myStringColumn = N'myFilter'它將以相同的方式工作。

現在為什么會發生這種情況以及為什么將列類型與您傳遞的參數相匹配很重要 - 因為如果參數不是列類型,那么 SQL 會將列中的所有值(基本上所有行)轉換為傳遞的參數類型在查詢中(不是其他方式) - 這就是為什么你有巨大的性能問題,在這種情況下基本上索引丟失,導致所有列值都被轉換為 varchar。

這里有一些更多的解釋 - https://www.sqlshack.com/query-performance-issues-on-varchar-data-type-using-an-n-prefix/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM