假设,我有一个从客户端发送的字符串列表,在这种情况下是区域。我有一个名为 Compliance Regions 的表。我想搜索具有名称属性和区域项的行应该存在于行上。
在 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;
生成的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]
和
--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]
)
根据要求添加了执行计划。
最佳答案
鉴于这两种选择,第二种可能更好,因为列名上没有函数调用。
然而,两者并不相同。第一个进行部分匹配,第二个进行完全匹配。你真的应该做你想做的事。性能次于准确性。
两人都是痛苦的看着。类型转换 CHARINDEX()
的输出到索引?我们可以说“多余”吗?
他们提出了为什么查询不简单的问题:
select . . .
from [Administration].[ComplianceRegions] AS [Extent1]
where Extent1.Name in (N'Canada', N'EN 50530');
这是此逻辑的最简单且性能最佳的版本。
关于SQL INNER JOIN 与 Where Exists 性能考虑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42808633/