SQL INNER JOIN vs存在性能考虑因素

Foy*_*rim 6 sql linq sql-server performance join

假设,我有一个从客户端发送的字符串列表,在本例中是区域.我有一张名为Compliance Regions的表格.我想搜索具有name属性的行,并且该行应该存在region项.

在LINQ中,我可以通过两种不同的方式完成它.如下所示,它们产生两种不同的SQL查询.我的问题是我应该选择哪个?哪个查询具有更好的性能?

 List<string> regions = new List<string>() { "Canada", "EN 50530" };

           var cregions = from c in complianceRegions
                           from r in regions
                           where c.Name.Equals(r)
                           select c;

            var cregions2 = from c in complianceRegions
                            where regions.Any(x => x == c.Name)
                            select c;
Run Code Online (Sandbox Code Playgroud)

生成的sql如下所示.

      -- cregions
   SELECT 
    [Extent1].[Id] AS [Id], 
    [Extent1].[Name] AS [Name], 
    [Extent1].[Description] AS [Description]
    FROM  [Administration].[ComplianceRegions] AS [Extent1]
    INNER JOIN  (SELECT 
        N'Canada' AS [C1]
        FROM  ( SELECT 1 AS X ) AS [SingleRowTable1]
    UNION ALL
        SELECT 
        N'EN 50530' AS [C1]
        FROM  ( SELECT 1 AS X ) AS [SingleRowTable2]) AS [UnionAll1] ON [Extent1].[Name] = [UnionAll1].[C1]  
Run Code Online (Sandbox Code Playgroud)

cregions

--cregions2
    SELECT 
    [Extent1].[Id] AS [Id], 
    [Extent1].[Name] AS [Name], 
    [Extent1].[Description] AS [Description]
    FROM [Administration].[ComplianceRegions] AS [Extent1]
    WHERE  EXISTS (SELECT 
        1 AS [C1]
        FROM  (SELECT 
            N'Canada' AS [C1]
            FROM  ( SELECT 1 AS X ) AS [SingleRowTable1]
        UNION ALL
            SELECT 
            N'EN 50530' AS [C1]
            FROM  ( SELECT 1 AS X ) AS [SingleRowTable2]) AS [UnionAll1]
        WHERE [UnionAll1].[C1] = [Extent1].[Name]
    )
Run Code Online (Sandbox Code Playgroud)

cregions2 根据要求添加了执行计划.

Gor*_*off 2

考虑到这两种选择,第二种可能更好,因为没有对列名的函数调用。

然而,两者并不相同。第一个进行部分匹配,第二个进行完全匹配。你真的应该做一件能达到你的目的的事情。性能仅次于准确性。

两人看着都心疼。将 的输出转换CHARINDEX()为索引?我们可以说“多余”吗?

他们提出一个问题,为什么查询不简单:

select . . .
from [Administration].[ComplianceRegions] AS [Extent1]
where Extent1.Name in (N'Canada', N'EN 50530');
Run Code Online (Sandbox Code Playgroud)

这是该逻辑最简单且性能最佳的版本。