hol*_*oly 5 sql vb.net linq-to-sql having-clause
根据所有示例,SQL转换为LINQ for HAVING子句,如下例所示:
SELECT NAME
FROM TABLES
GROUP BY NAME
HAVING COUNT(*) > 1
Run Code Online (Sandbox Code Playgroud)
是:(vb.net)
from t in tables
group t by t.NAME into g = Group
where g.count > 1
select g
Run Code Online (Sandbox Code Playgroud)
但是上面的LINQ语句被翻译成以下SQL:
SELECT [t1].[NAME] AS [Key]
FROM (
SELECT COUNT(*) AS [value], [t0].[NAME]
FROM [tables] AS [t0]
WHERE [t0].[NAME] <> @p0
GROUP BY [t0].[NAME]
) AS [t1]
WHERE [t1].[value] > @p1
Run Code Online (Sandbox Code Playgroud)
我从未成功生成LINQ的HAVING子句.假设使用WHERE的HAVING和子查询分组在结果中是等价的,但是性能有差异吗?那么保持我的原始SQL查询至少与LINQ生成底层的SIMILAR一样?
您可以通过查看执行计划来演示 SQL Server 是否以相同的方式执行相关的两个查询。采取以下测试代码(我使用的是SQL Server 2008):
CREATE TABLE #TABLES ([ID] INT IDENTITY, [Name] VARCHAR(30))
INSERT INTO #TABLES VALUES('A')
INSERT INTO #TABLES VALUES('A')
INSERT INTO #TABLES VALUES('B')
INSERT INTO #TABLES VALUES('C')
INSERT INTO #TABLES VALUES('D')
SELECT NAME
FROM #TABLES
WHERE [Name] <> 'D'
GROUP BY NAME
HAVING COUNT(*) > 1
SELECT [t1].[NAME]
FROM (
SELECT COUNT(*) AS [value], [t0].[NAME]
FROM [#TABLES] AS [t0]
WHERE [t0].[NAME] <> 'D'
GROUP BY [t0].[NAME]
) AS [t1]
WHERE [t1].[value] > 1
DROP TABLE #TABLES
Run Code Online (Sandbox Code Playgroud)
从 SQL 查询分析器执行这些查询并在“查询”菜单下选择“包括实际执行计划”将产生以下输出:

在这种情况下,由于生成的查询计划完全相同,因此您的 SQL 和从 LINQ 语句生成的 SQL 之间显然不应该存在性能差异。
顺便说一句,不幸的是,我找不到任何文档来说明为什么 LinqToSql 不使用 HAVING,或者使用 HAVING 与使用子选择是否会以某种方式提高性能。如果我不得不猜测的话,我会说 SQL Server 中的查询优化器在执行这些语句之前在内部将它们转换为相同的查询,这就是为什么这两个语句的执行计划相同。无论我之前的说法是否正确,我想说的是,如果您有疑问,只需查看您的 SQL 版本与 LinqToSql 版本的执行计划即可。如果它们相同,那么您就无需担心性能问题。如果您的 SQL 版本效率更高,那么您始终可以编写一个存储过程,然后使用 LinqToSql 调用该存储过程。
| 归档时间: |
|
| 查看次数: |
1631 次 |
| 最近记录: |