【问题标题】:What's optimal? UNION vs WHERE IN (str1, str2, str3)什么是最优的? UNION vs WHERE IN (str1, str2, str3)
【发布时间】:2010-09-06 17:07:16
【问题描述】:

我正在编写一个程序,它会在客户的特定当地时间发送一封电子邮件。我有一个 .NET 方法,它采用时区和时间以及目标时区并返回该时区的时间。所以我的方法是选择数据库中的每个不同的时区,使用该方法检查它是否是正确的时间,然后选择具有该时区的数据库中的每个客户端。

查询将类似于其中之一。请记住,结果集的顺序无关紧要,所以联合就可以了。哪个跑得更快,或者他们真的做同样的事情?

SELECT email FROM tClient WHERE timezoneID in (1, 4, 9)

SELECT email FROM tClient WHERE timezoneID = 1
    UNION ALL SELECT email FROM tClient WHERE timezoneID = 4
    UNION ALL SELECT email FROM tCLIENT WHERE timezoneID = 9

编辑:timezoneID 是 tTimezone 的外键,是一个主键 timezoneID 和 varchar(20) 字段 timezoneName 的表。 另外,我选择了WHERE IN,因为我不想打开分析器。

编辑 2:查询在 100 毫秒内处理 200k 行,所以到此我完成了。

【问题讨论】:

  • 把它交给查询分析器

标签: sql optimization


【解决方案1】:

嘿!这些查询是不等价的。

仅当假设一封电子邮件仅属于一个时区时,结果才会相同。当然可以,但是 SQL 引擎不知道这一点,并试图消除重复。所以第一次查询应该更快。

始终使用 UNION ALL,除非您知道为什么要使用 UNION。

如果您不确定有什么区别,请参阅this SO question。

注意:那个叫喊属于问题的previous version

【讨论】:

    【解决方案2】:

    对于大多数与数据库相关的性能问题,真正的答案是运行它并分析数据库为您的数据集做了什么。运行解释计划或跟踪以查看您的查询是否命中正确的索引或在必要时创建索引。

    我可能会选择第一个使用 IN 子句,因为它包含您想要的最多语义。 timezoneID 似乎是某个时区表上的主键,因此它应该是电子邮件上的外键并被索引。根据数据库优化器,我认为它应该对外键索引进行索引扫描。

    【讨论】:

      【解决方案3】:

      我的第一个猜测是

      SELECT email FROM tClient WHERE timezoneID in (1, 4, 9)
      会更快,因为它只需要对表进行一次扫描即可找到结果,但我建议检查两个查询的执行计划。

      【讨论】:

        【解决方案4】:

        我手头没有 MS SQL 查询分析器来实际检查我的假设,但我认为 WHERE IN 变体会更快,因为使用 UNION 服务器将必须进行 3 次表扫描,而使用 WHERE IN 将只需要一次。如果您有查询分析器,请检查两个查询的执行计划。

        在 Internet 上,您可能经常会遇到避免使用 WHERE IN 的建议,但这是指使用子查询的情况。所以这个案例不在本建议的范围内,而且更容易阅读和理解。

        【讨论】:

          【解决方案5】:

          我认为问题中缺少几个非常重要的信息。首先,天气 timezoneID 是否被索引非常重要,它是否是主键的一部分等。我建议大家看看分析器,但根据我的经验,WHERE 子句应该更快,尤其是一个索引。逻辑类似于,联合查询中存在额外的开销,检查类型,每个中的列号等。

          【讨论】:

            【解决方案6】:

            在“SQL 性能调优”一书中,作者发现 UNION 查询在他们测试的所有 7 个 DBMS(SQL Server 2000、Sybase ASE 12.5、Oracle 9i、DB2 等)中都比较慢:http://books.google.com/books?id=3H9CC54qYeEC&pg=PA32&vq=UNION&dq=sql+performance+tuning&source=gbs_search_s&sig=ACfU3U18uYZWYVHxr2I3uUj8kmPz9RpmiA#PPA33,M1

            后来的 DBMS 可能已经优化了这种差异,但这值得怀疑。此外,与 IN 相比,UNION 方法更长且更难维护(如果您想要第三个怎么办?)。

            除非您有充分的理由使用 UNION,否则请坚持使用 OR/IN 方法。

            【讨论】:

              【解决方案7】:

              一些 DBMS 的查询优化器会修改您的查询以使其更高效,因此根据您使用的 DBMS,您可能不必在意。

              【讨论】:

                猜你喜欢
                • 2020-11-14
                • 2010-09-16
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2015-05-14
                • 1970-01-01
                • 1970-01-01
                • 2019-12-15
                相关资源
                最近更新 更多