假设我有一个名为PEOPLE
的表格,其中有3列ID, LastName, FirstName
,这些列都没有编入索引。
LastName
更独特,FirstName
不那么独特。
如果我进行2次搜索:
select * from PEOPLE where FirstName="F" and LastName="L"
select * from PEOPLE where LastName="L" and FirstName="F"
我的信念是第二个更快,因为更独特的标准(LastName
)首先出现在where
子句中,并且记录将更有效地消除。我认为优化器不够智能,无法优化第一个sql。
我的理解是否正确?
答案 0 :(得分:80)
不,这个顺序无关紧要(或至少:无所谓)。
任何体面的查询优化器都会查看所有 WHERE
子句的各个部分,并找出满足该查询的最有效方法。
我知道SQL Server查询优化器会选择一个合适的索引 - 无论你有哪两个条件。我假设其他RDBMS也有类似的策略。
重要的是你是否有合适的索引!
对于SQL Server,如果您有以下内容,它可能会使用索引:
(LastName, FirstName)
(FirstName, LastName)
(LastName)
或(FirstName)
(或两者)另一方面 - 再次针对SQL Server - 如果您使用SELECT *
从表中抓取所有列,并且表格相当小,那么查询很有可能优化器只会执行一个表(或聚簇索引)扫描,而不是使用索引(因为查找完整数据页以获得所有其他列的速度非常快)。
答案 1 :(得分:11)
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语句中子句的顺序。
答案 2 :(得分:9)
ANSI SQL Draft 2003 5WD-01-Framework-2003-09.pdf
6.3.3.3规则评估顺序
...
如果优先级不是由格式或括号确定的,则表达式的有效评估通常从左到右执行。但是,依赖于实现是否实际上是从左到右计算表达式,特别是当操作数或运算符可能导致条件被引发时,或者如果可以在不完全评估表达式的所有部分的情况下确定表达式的结果。
从here
复制答案 3 :(得分:2)
不,所有RDBM首先通过分析查询并通过重新排序where子句来优化它。
根据您使用的RDBM,可以显示分析的结果(例如,在oracle中搜索解释计划)
微米。
答案 4 :(得分:1)
原始OP声明
我认为第二个更快,因为更独特的标准(LastName)首先出现在&gt; where子句中,并且记录将更有效地消除。我认为优化器不够智能,无法优化第一个sql。
我猜你在创建索引时选择列的顺序会让你感到困惑,因为你必须把选择性较高的列放在第一位,而不是第二选择性的列,等等。
BTW,对于上述两个查询,SQL Server优化器不会进行任何优化,但只要计划的总成本低于并行度阈值成本,就会使用Trivila计划。答案 5 :(得分:0)
假设名称没有编入索引,它就是这样。 但是不同的数据会使它错误。为了找出哪种方法可能会有所不同,DBMS必须为每一列运行一个不同的计数查询并比较数字,这将不仅仅是耸耸肩而且还要继续使用它。