【问题标题】:Which SQL Query is Better?哪个 SQL 查询更好?
【发布时间】:2010-01-13 01:47:18
【问题描述】:

这是不是SQL查询语句:

SELECT p.id, p.[name], SUM(ps.sales_amount) AS GROSS_SALES
FROM products p
  LEFT OUTER JOIN product_sales ps ON p.id = ps.product_id
GROUP BY p.id, p.[name]

优于:

SELECT SUM([t2].[value]) AS [SalesAmount], [t2].[id] AS [ProductId], [t2].[name] AS [ProductName]
FROM (
    SELECT (
        SELECT SUM([t1].[sales_amount])
        FROM [dbo].[product_sales] AS [t1]
        WHERE [t1].[product_id] = [t0].[id]
        ) AS [value], [t0].[id], [t0].[name]
    FROM [dbo].[products] AS [t0]
    ) AS [t2]
GROUP BY [t2].[id], [t2].[name]

第二个是 LINQ2SQL 查询的结果。仍在寻找重新编写 LINQ 表达式的方法...

示例中最优化的 SQL 查询是什么?

你的想法?谢谢!

【问题讨论】:

  • 没有安装 SQL Profiler...很遗憾
  • 您不需要 Profiler。只需在运行查询之前使用 SET SHOWPLAN_TEXT。
  • 或者按 ctrl-K(或者 ctrl-M,我不记得了)
  • 第一个维护成本更低
  • @dan - 不是真的。生成第二个。它的成本会低得多。

标签: sql sql-server-2005 linq-to-sql database


【解决方案1】:

真正的答案是不测量就无法判断。即使那样,除非您在真实数据集上进行测量,否则您也不会真正知道。

查看这个blog post(不是我写的),其中生成的 sql 看起来更糟,但性能要好得多。他的示例专门处理子选择与连接,因此我认为这与您的情况非常相关。

【讨论】:

  • LEFT JOIN/IS NULL 错误很常见。它会阻止 SQL Server 执行反半联接,并且几乎不会像人们认为的那样执行。记住这一点很好,但在这里并不真正适用,因为这不是反连接。
  • 是的。这不是关于反半连接,但我从博客文章中得到的是,有时优化器和/或 LINQ 比我更聪明。 :) 我认为这可能适用于此。
【解决方案2】:

嗯,第一个查询更好,因为它更具可读性。但是,由于生成了第二个查询而不是解释它,并且由于您不必(不应该)处理从 LINQ 表达式生成的实际 SQL,因此第二个查询可能没有问题。

我假设 SQL Server 引擎可以像第一个查询一样将其展平为标准连接。如果您想知道启动 SQL Server Management Studio 并查看两者的实际执行计划。

【讨论】:

    【解决方案3】:

    作为一般陈述,这似乎是一个相当滥用的子查询,在此基础上,我预测第一个查询会更快。为什么不试试看呢?

    【讨论】:

      【解决方案4】:

      第一个更有效。一般来说,连接比子查询好。 MS-sql 并不总是将子查询优化为它们的逻辑“连接”等价物。查询是如此之小,但两者都应该相当不错,而且可能没有什么区别。您需要查看 查询计划 以了解差异,或者查看两者都使用 trace 执行。

      当然,第一个也更具可读性。这就是你现在使用 Linq-to-SQL 会得到的东西。当然,重点是你不应该自己处理sql。

      故事是 Linq-to-Sql 生成的查询会越来越高效。

      【讨论】:

      • 您是否真的检查过 SQL Server 对第二个查询做了什么?
      • 如果不知道这种情况下的查询重写器和优化器是如何工作的,就不能这么说
      • 不,除非有人检查,否则无法确定,这就是为什么我(和大多数其他人)建议进行实际检查的原因。还有其他因素。有索引吗?是否有涵盖的索引?当它移动到 2008 年时呢?这些表的 size 会影响 sql 的索引/优化决策。我对我的回答很满意,但我需要坐在他的机器上才能真正进行比较。对于每个查询,这就是我们所有人所做的吗?进行广泛的分析?不,我们没有。我们根据知识和经验做出最好的猜测,然后继续前进。第一个可能更好,如果重要,请检查。
      【解决方案5】:

      我的预感是两者在性能方面应该是相同的。左连接可能会是一个嵌套循环连接,这正是子查询版本所做的。

      但不要相信我的话 - 正如其他人所建议的那样,请查看执行计划并亲自看看哪个更好。或者打开客户统计,看看哪一项需要更长的时间。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-12-16
        • 2010-10-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-09
        相关资源
        最近更新 更多