2012-07-11 87 views
75

假设我有一张名为PEOPLE的表,其中有3列ID, LastName, FirstName,这些列都没有索引。
LastName更加独特,并且FirstName不太独特。SQL中where子句的顺序是否重要

如果我做2个搜索:

select * from PEOPLE where FirstName="F" and LastName="L" 
select * from PEOPLE where LastName="L" and FirstName="F" 

我的信念是,第二个是快的,因为更独特的标准(LastName)至上的where子句中,并记录将得到更有效地消除。我不认为优化器足够聪明,可以优化第一个sql。

我的理解是否正确?

+7

不,这个顺序并不重要 - 任何像样的查询优化器都会查看全部** WHERE子句并找出满足该查询的最有效方式 – 2012-07-11 15:50:01

+3

当您运行这两个语句时,您的观察结果如何?执行计划是什么样子的? – 2012-07-11 15:51:53

+3

您是指特定的RDBMS吗?确实存在差异。 – Bjoern 2012-07-11 15:52:36

回答

64

不,这个顺序无关紧要(或者至少:应该不重要)。

任何像样的查询优化器将查看全部条款的部分并找出满足该查询的最有效方式。

我知道SQL Server查询优化器会选择一个合适的索引 - 无论哪个顺序你有两个条件。我假设其他RDBMS将有类似的策略。

重要的是您是否有合适的索引!

在SQL Server的情况下,如果您有它可能会使用一个索引:

  • (LastName, FirstName)
  • 索引的索引上(FirstName, LastName)
  • 指数上只是(LastName),或者只是(FirstName) (或两者)

在另一方面 - 再次为SQL Server - 如果你使用SELECT *所有列都来自一个表,并且该表非常小,那么查询优化器就只是执行表(或聚簇索引)扫描而不是使用索引(因为查找完整数据页以获取全部其他列只是非常快速变得非常昂贵)。

+0

如果没有索引(es)op可能是正确的,这取决于数据。当没有索引的情况下做这样的事情时,会是一个奇怪的决定... – 2012-07-11 15:57:24

+0

@TonyHopkinson:我不这么认为 - 即使没有索引,我也怀疑它们之间有什么不同。毕竟:没有索引,除了全表扫描,RDBMS还能做什么呢? – 2012-07-11 15:58:53

+2

SQL服务器有趣的一面说明,显然谓词内NOT EXISTS的顺序实际上可以影响计划创建:http://bradsruminations.blogspot.com/2010/04/looking-under-hood.html – 2012-07-11 16:03:07

2

不,所有RDBM首先通过分析查询并通过重新排序where子句来优化它。

根据其RDBM你是你使用可以显示什么的分析结果(搜索在Oracle例如解释计划)

M.

+0

它是基于索引。所以它在内容方面是间接的。 – 2012-07-11 15:54:42

+0

实际上,这主要是基于表统计信息完成 – poussma 2012-07-11 15:56:42

9

的WHERE子句中不应该有次序符合SQL标准的数据库中的差异。在大多数数据库中不保证评估顺序。

不要以为SQL关心订单。下面的命令生成的SQL Server错误:

select * 
from INFORMATION_SCHEMA.TABLES 
where ISNUMERIC(table_name) = 1 and CAST(table_name as int) <> 0 

如果此条款的第一部分被处决第一,那么只有数字表名称将被转换为整数。但是,它失败了,提供了一个清晰的例子,SQL Server(与其他数据库一样)不关心WHERE语句中子句的顺序。

+0

导致错误的查询与WHERE谓词评估的顺序有什么关系? – Jim 2012-07-11 19:12:54

+3

@Jim如果'ISNUMERIC(table_name)= 1'被首先评估,那么'CAST'只会被称为数字表名称。但是,由于它不是首先被评估,所以'CAST'也被评估为非数字表名,导致错误信息。 – hibbelig 2013-02-13 10:43:40

+0

非常好的说明 – neeohw 2017-07-19 09:02:57

0

它是真实的,只要它去,假设名称没有索引。 虽然不同的数据会导致错误。为了找出哪种方法可以做到这一点,每次都会有所不同,数据库管理系统将不得不针对每一列运行不同的计数查询并比较数字,这将花费更多的成本,而不仅仅是耸耸肩并继续进行。

6

ANSI SQL草案2003 5WD-01-Framework的2003-09.pdf

6.3.3.3规则评估顺序

...

当优先级不是由格式确定或通过括号,表达的有效评估通常从左到右进行。但是,实现依赖于表达式实际上是否从左到右进行了评估,特别是在操作数或运算符可能导致条件被引发时,或者如果可以在不完全评估表达式的所有部分的情况下确定表达式的结果。

here

1

原始OP语句复制

我的信念是,第二个是快的,因为更独特的标准(姓氏)是第一位在> where子句,并记录将被淘汰更多有效率的。我不认为优化器足够聪明,可以优化第一个sql。

我想你是混淆这与选择列的顺序,同时创建索引,你必须把第一选择性列比第二选择性更高,等等。

顺便说一句,对于上述两个查询SQL服务器优化器不会做任何优化,但只要计划的总成本低于并行阈值成本,就会使用Trivila计划。