什么是最佳的? UNION与WHERE IN(str1,str2,str3)

时间:2008-08-24 16:53:34

标签: sql optimization

我正在编写一个程序,在客户特定的当地时间发送电子邮件。我有一个.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的外键,tTimezone是一个包含主键timezoneID和varchar(20)字段timezoneName的表。 另外,由于我不想打开分析仪,我选择了WHERE IN

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

7 个答案:

答案 0 :(得分:3)

嘿!这些查询不等效。

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

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

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

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

答案 1 :(得分:2)

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

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

答案 2 :(得分:1)

我的第一个猜测是

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

< / p>

答案 3 :(得分:1)

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

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

答案 4 :(得分:1)

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

答案 5 :(得分:1)

在“SQL性能调优”一书中,作者发现UNION查询在他们测试的所有7个DBMS中都较慢(SQL Server 2000,Sybase ASE 12.5,Oracle 9i,DB2等):{{3 }}

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

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

答案 6 :(得分:0)

某些DBMS的查询优化器会修改您的查询以提高查询效率,因此根据您使用的DBMS,您可能不应该关心。