【问题标题】:Which of these SQL queries is better and why?这些 SQL 查询中哪个更好,为什么?
【发布时间】:2016-01-17 21:59:31
【问题描述】:

我还在学习 SQL。我以两种不同的方式完成了类似的查询,想知道哪个更好以及为什么。

UPDATE R
    SET R.something = 1
    FROM Table1 R
    JOIN Table2 U
    ON R.value1 = U.value2
    WHERE
        U.value3 BETWEEN 1 AND 5

UPDATE R
    SET R.something = 1
    WHERE R.value1 IN
    (SELECT U.value2
    FROM U
    WHERE
        U.value3 BETWEEN 1 AND 5
    )

【问题讨论】:

  • 你检查查询执行计划了吗?
  • 太棒了!不知道执行计划。据我所知,它们看起来完全一样。但这似乎不正确。
  • 优化器优化 :) 如果统计信息/索引相似,两条语法截然不同的 SQL 语句看起来与数据库引擎相似。

标签: sql optimization


【解决方案1】:

您的问题没有一个单一的答案。 SQL 是一种描述性语言,而不是一种过程语言。这取决于效率更高的数据库引擎。此外,索引会对性能产生很大影响。

顺便说一句,您的两个查询并不相同。当“U”中有多个值时,第一个可以返回多行。带有“IN”的版本会隐含“DISTINCT”。要解决此问题,您需要添加特定的“DISTINCT”。

UPDATE R
    SET R.something = 1
    FROM Table1 R
         JOIN (select distinct value2
               from Table2 U
               WHERE U.value3 BETWEEN 1 AND 5 
              ) u
         ON R.value1 = U.value2  

另外,虽然我个人喜欢更新中的“FROM”语句,但并非所有数据库都支持它。带有“IN”的版本兼容更广泛的数据库引擎。

【讨论】:

    【解决方案2】:

    这完全取决于您计划使用的数据库(Oracle、SQL Server 等)、它的版本,有时还取决于表中的数据量。但通常你应该更喜欢 JOIN,因为它们对大多数优化器来说更容易,并且带有 null 的陷阱更少。

    【讨论】:

    • 我想不出一个例子,其中 Null 值会影响 JOIN 与 IN 你能提供一个吗?
    • “使用 IN 或 NOT IN 与 test_expression 进行比较的子查询或表达式返回的任何空值都返回 UNKNOWN。将空值与 IN 或 NOT IN 一起使用会产生意外结果。”。见msdn.microsoft.com/en-us/library/ms177682.aspx
    • 这是一个很好的引用,但这不是一个例子,也没有解释 JOIN 会有什么不同。 Here's an example JOIN 和 IN 的行为是相同的。你能试着创造一个没有的地方吗?否则我仍然会对你所说的 less gotchas with nulls 感到困惑
    【解决方案3】:

    第一个查询更好。

    无论您使用的是什么实际的 DBMS,关系型数据库的构建都是为了以这种方式连接数据并使用 where 子句对其进行过滤。这是他们的面包和黄油。在第二个查询中,您使用子查询来收集其他数据。这太酷了,关系数据库也能很好地解决这个问题。但是,对于子查询,在这种特定情况下,您最终会得到两个查询,一个是获取 U 数据,然后是外部查询,使用子查询中的数据来设置 R 数据。

    这里有一些棘手的地方。在您的查询中,您的子查询完全引用了一个单独的表。所以还是会很快。该子查询仅包含在 U 数据中。您将获得 2 个查询 - 获取 U 数据,然后使用 U 数据更新 R 数据。但是,如果您编写了一个类似的查询,其中子查询引用了 R 中的数据,那么您将不会得到两个单独的查询。你最终会对 R 中的所有数据进行全表扫描,这会相当慢。

    为了更完整而进行编辑:正如其他人所说,很大程度上取决于您使用的是什么 DBMS 以及它最擅长什么。当第一次学习 SQL(我绝不是专家)时,其中一个障碍是意识到有很多方法可以做同样的事情,得到同样的结果,然后往往最终会针对同样的事情进行优化.因此,寻找“正确”的方式往往是徒劳的,因为没有明确的“正确”方式。我尝试编写不仅是为了正确性和速度,也是为了可维护性——我发现子查询对大脑来说可能比必要的更难。如果可以避免它们,我会尝试不使用它们(只要替代方案不是光标或其他东西 :-D)。

    【讨论】:

      【解决方案4】:

      使用 JOIN 查询会更好,因为它比子选择更快。

      【讨论】:

      • 嗯,OP 说执行计划是相同的,所以看起来不太可能
      【解决方案5】:

      这可能取决于您使用的引擎,但我相信 MS SQL Server 会针对相同的查询计划进行优化。

      如果一个引擎没有,我会建议在这种情况下它是劣等的。

      【讨论】:

        【解决方案6】:

        取决于数据库和数据库版本 搜索 IN 或 JOIN 是否更好(更快)返回不同 结果(IN 更快或 JOIN 更快)取决于数据库 甚至在 SQL 语句上 - 它甚至可以根据 数据库版本。使用多个数据进行测试总是一个好主意 尺寸和不同的平台!

        (查询 #2 是最容易阅读的,但可能会也可能不会更慢)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-04-14
          • 2014-03-12
          • 1970-01-01
          • 2016-09-03
          • 2022-01-15
          • 1970-01-01
          相关资源
          最近更新 更多