简体   繁体   中英

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

I have a query that joins to a sub query. When an indexed nvarchar column is passed in as a string literal, the performance tanks. However, when I pass in the same value as a parameter, the execution plan changes drastically and the query executes quickly. I apologize for naming.

In the situation below, myStringColumn is indexed and the tables have millions of rows.

This one is bad:

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

This one is good:

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

What I do not understand is why the performance of the second is so much better. From what I can tell, it's because the nested loops join in the plan is much better in the second query, but I do not understand why. My guess is that for some reason SQL Server is having to loop through more rows for each iteration in the first, but I am at a loss as to why only changing to a parameter vs a string literal would have that much affect.

Questions: Why is the second query better than the first? What is SQL Server doing that makes the first so much slower?

Thank you.

The difference is that when you declare parameter you doing it correctly with N prefix and declaring variable as N varchar, same as your column. While when you do WHERE - you are not adding N prefix, so internally varchar variable created, if you would do myStringColumn = N'myFilter' it would work the same way.

Now why is this happening and why it is important to match column type to parameters you passing - is because if parameter is not of column type, then SQL will convert ALL values in the column (so basically all rows) to the type of parameter passed in query (not other way around) - so that's why you have huge performance problem, basically index is lost in this case, cause all column values are being CONVERTED to varchar.

Here are some more explanations - https://www.sqlshack.com/query-performance-issues-on-varchar-data-type-using-an-n-prefix/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM