6

我正在编写一个程序,在客户的特定当地时间发送一封电子邮件。我有一个 .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 行,所以现在我完成了。

4

7 回答 7

3

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

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

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

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

注意:那个叫喊属于以前版本的问题。

于 2008-08-24T19:25:50.520 回答
2

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

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

于 2008-08-24T17:00:45.143 回答
1

我的第一个猜测是

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

于 2008-08-24T16:58:30.937 回答
1

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

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

于 2008-08-24T17:03:58.787 回答
1

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

于 2008-08-24T18:07:58.163 回答
1

在“SQL 性能调优”一书中,作者发现他们测试的所有 7 个 DBMS(SQL Server 2000、Sybase ASE 12.5、Oracle 9i、DB2 等)中的 UNION 查询都比较慢: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 方法。

于 2008-08-24T18:58:53.110 回答
0

一些 DBMS 的查询优化器会修改您的查询以使其更有效,因此根据您使用的 DBMS,您可能不应该关心。

于 2008-08-24T17:28:11.380 回答