什么是最佳? UNION与WHERE IN(str1,str2,str3)
我正在编写一个程序,该程序在客户的特定本地时间发送电子邮件。我有一个.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行,因此我已经完成了。
解决方案
回答
我的第一个猜测是
SELECT email FROM tClient WHERE timezoneID in (1, 4, 9)
这样做会更快,因为它只需要扫描表一次即可找到结果,但是我建议检查两个查询的执行计划。
回答
对于大多数与数据库有关的性能问题,真正的答案是运行它并分析数据库对数据集所做的工作。运行说明计划或者跟踪,以查看查询是否达到正确的索引,或者在必要时创建索引。
我可能会第一个使用IN子句,因为它带有我们想要的大部分语义。 timezoneID似乎是某个时区表上的主键,因此它应该是电子邮件上的外键并已建立索引。取决于数据库优化器,我认为它应该对外键索引进行索引扫描。
回答
我没有手头的MS SQL查询分析器来实际检查我的假设,但认为WHERE IN变体会更快,因为使用UNION服务器将必须进行3次表扫描,而使用WHERE IN则只需要进行一次表扫描。如果我们有查询分析器,请检查两个查询的执行计划。
在Internet上,我们可能经常会遇到避免使用WHERE IN的建议,但这是指对使用过的子查询进行查询的情况。因此,这种情况超出了本建议的范围,并且更易于阅读和理解。
回答
一些DBMS的查询优化器会修改查询以使其更有效,因此,根据我们使用的DBMS,我们可能不必在意。
回答
我认为问题中缺少一些非常重要的信息。首先,天气timezoneID是否被索引,是否为主键的一部分等非常重要。我建议大家看看分析器,但以我的经验,WHERE子句应该更快,尤其是索引。逻辑类似,联合查询,检查类型,每个中的列号等都有额外的开销。
回答
在" SQL Performance Tuning"一书中,作者发现在他们测试的所有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方法。
回答
仅当假设一封电子邮件仅属于一个时区时,结果才会相同。但是,SQL引擎当然不知道这一点,并尝试删除重复项。因此,第一个查询应该更快。
始终使用UNION ALL,除非我们知道为什么要使用UNION。
如果我们不确定有什么区别,请参阅此SO问题。
注意:大喊属于问题的先前版本。