SQL - WHERE条件的顺序是否重要?

105
假设 category_id 是表 books 的索引键(非主键),下面两个 SQL 语句有什么区别吗?
SELECT * FROM books WHERE author='Bill' AND category_id=1

SELECT * FROM books WHERE category_id=1 AND author='Bill'

我猜先根据 category_id 过滤记录,然后再根据 author 过滤比倒序过滤更快。SQL 引擎能聪明到用这种方式吗?


1
我在发布之前进行了搜索。有人知道如何编辑此帖子,以便在以后其他人有相同问题时更容易被搜索到吗? - powerboy
@OMG_Remus Rusanu最近在一个问题中发布了这个链接。也许是这个链接吗?http://rusanu.com/2009/09/13/on-sql-server-boolean-operator-short-circuit/ - Martin Smith
@Martin Smith:不知道 Remus 有博客,非常酷。有博客链接发布的位置吗? - OMG Ponies
@OMG - 是的,就在这里... http://stackoverflow.com/questions/3088709/what-is-query-execution-doing-to-this-query-in-sql-server-2005/3088835#3088835 - Martin Smith
5个回答

103

不,WHERE子句的顺序并不重要。

优化器会审视查询并根据索引等因素确定获取数据的最佳方式。即使在category_id和author列上存在覆盖索引,任何一个都满足使用它的条件(假设没有更好的选择)。


虽然我同意,但是我要补充一点,那就是当使用或语句时,我会调整逻辑顺序,以便可以立即通过,或者当使用与语句时,可能会立即失败。如果能够立即找出答案,就不需要检查其他标准了。 - spinon
过时的统计数据会对此产生影响吗? - Abe Miessler
1
@Abe Miessler:是的,统计信息和索引过时会对优化器的选择产生负面影响。但是数据越多,保持这些信息最新的成本就越高。 - OMG Ponies
MySQL也是同样的情况吗? - Drew
2
据我所知,这适用于数据库(除了NoSQL变体)。 - OMG Ponies
这样怎么样?Where isnumeric(MyNvarchar) = 1 and convert(numeric, MyNvarchar) > 5. 我的MyNvarchar有时是数字。如果先应用第二个条件,有时会失败。 - TizzyFoe

20

SQL是声明式的。

在您的示例中,您已经告诉了引擎/优化器您想要什么......现在它将找出最佳方法来实现该操作(在合理范围内和“成本”将是不相关的话题)。


6
赞同这个正确的陈述。话虽如此,Prolog是一种声明式语言,但在我使用的实现中,条件的顺序是有影响的。 - Justin K

9

一般情况下,如果你使用的是现代数据库,那么不需要考虑这个问题。也许在十年前,这个问题会比较重要。


是的。似乎Oracle基于规则的优化器(RBO)会在制定执行计划时查看where子句中谓词的顺序。 - Shannon Severance
4
感谢您建议,认为老的关系型数据库系统可能没有此功能。 - marknuzz

3
简而言之,不需要,因为优化器会确定获取数据的最佳方式。

1

是的,SQL是一种声明性语言。但在SQL Server中(不确定其他引擎),DBA实际上可以通过在SQL查询存储中强制执行计划来实现这一点。

enter image description here

但是,你不能从你的应用程序或查询文本本身中控制它。
P.S. 另外两个建议:你可以使用 "FORCE ORDER" 控制 JOIN 的顺序。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接