LINQ TO SQL GROUP BY HAVING 仅作为子查询生成

发布于 2024-12-11 23:37:05 字数 666 浏览 0 评论 0原文

根据所有示例,HAVING 子句的 SQL 转换为 LINQ,如下例所示:

SELECT NAME
FROM TABLES
GROUP BY NAME
HAVING COUNT(*) > 1

是: (vb.net)

from t in tables 
group t by t.NAME into g = Group 
where g.count > 1 
select g

但上述 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

我从未成功地从 LINQ 生成 HAVING 子句。 假设 HAVING 和子查询 group by with WHERE 在结果上是等效的,但是性能上有区别吗?让我的原始 SQL 查询至少与 LINQ 生成的底层查询相似怎么样?

according to all samples, the SQL conversion to LINQ for HAVING clause as in this example:

SELECT NAME
FROM TABLES
GROUP BY NAME
HAVING COUNT(*) > 1

is: (vb.net)

from t in tables 
group t by t.NAME into g = Group 
where g.count > 1 
select g

BUT the above LINQ statement is translated to the following 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

I never succeed in generating HAVING clause form LINQ.
Let's say HAVING and subquery group by with WHERE are equivalent in results, but is there a difference in performance? what about keeping my original SQL queries at least SIMILAR to the ones LINQ generates underlying?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

街角迷惘 2024-12-18 23:37:05

您可以通过查看执行计划来演示 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

从 SQL 查询分析器执行这些查询,并在“查询”菜单下选择“包括实际执行计划”,将产生以下输出:

执行计划

在这种情况下,由于生成的查询计划完全相同,因此您的 SQL 和从您的 SQL 生成的 SQL 之间显然不应该存在性能差异。 LINQ 语句。

顺便说一句,不幸的是,我找不到任何文档来说明为什么 LinqToSql 不使用 HAVING,或者使用 HAVING 与使用子选择是否会以某种方式提高性能。如果我不得不猜测的话,我会说 SQL Server 中的查询优化器在执行这些语句之前在内部将它们转换为相同的查询,这就是为什么这两个语句的执行计划是相同的。无论我之前的说法是否正确,我想说的是,如果您有疑问,只需查看您的 SQL 版本与 LinqToSql 版本的执行计划即可。如果它们相同,那么您就无需担心性能问题。如果您的 SQL 版本效率更高,那么您始终可以编写一个存储过程,然后使用 LinqToSql 调用该存储过程。

You can demonstrate whether or not the two queries in question are executed in the same fashion by SQL Server by viewing the Execution Plans. Take the following test code (I used 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

Executing these queries from SQL Query Analyzer with "Include Actual Execution Plan" selected under the "Query" menu will yield the following output:

execution plans

In this case, since the generated query plans are exactly the same, it certainly appears that there should be no performance difference between your SQL and the SQL generated from your LINQ statement.

As a side note, unfortunately, I couldn't find any documentation on why LinqToSql doesn't make use of HAVING, or if using HAVING vs. using a sub select yields a performance gain one way or the other. If I had to guess I'd say the query optimizer in SQL Server internally turns these statements into the same query before they are executed, which is why the Execution Plans are identical for both statements. Whether or not my previous statement is true, I would say that if you're ever in doubt, just check out the Execution Plans for your SQL version versus the LinqToSql version. If they are the same then you've got nothing to worry about performance-wise. If your SQL version is much more efficient, then you could always write a stored procedure and just call the stored procedure using LinqToSql.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文