146

假设我有一个名为PEOPLE的表,它具有三列IDLastNameFirstName。这些列都没有被索引。 LastName更独特,FirstName不那么独特。

如果我进行两次搜索:

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

我的信念是第二个更快,因为更独特的标准 ( LastName) 在where子句中首先出现,并且记录将被更有效地消除。我认为优化器不够聪明,无法优化第一个 SQL 查询。

我的理解正确吗?

4

6 回答 6

118

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

任何体面的查询优化器都会查看子句的所有部分WHERE并找出满足该查询的最有效方法。

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

重要的是你是否有一个合适的索引!

对于 SQL Server,如果您有以下情况,它可能会使用索引:

  • 上的索引(LastName, FirstName)
  • 上的索引(FirstName, LastName)
  • (LastName)just或 just (FirstName)(或两者)上的索引

另一方面 - 再次对于 SQL Server - 如果您使用从表SELECT *中获取所有列,并且表相当小,那么查询优化器很有可能只进行表(或聚集索引)扫描而不是使用一个索引(因为查找完整数据页面以获取所有其他列很快就会变得太昂贵)。

于 2012-07-11T15:50:42.987 回答
23

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 语句中子句的顺序。

于 2012-07-11T15:52:18.623 回答
10

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

6.3.3.3 规则评估顺序

...

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

从这里复制

于 2012-07-11T15:55:45.480 回答
4

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

根据您使用的 RDBM 可以显示分析的结果(例如在 oracle 中搜索解释计划)

M。

于 2012-07-11T15:51:32.563 回答
2

就目前而言,这是真的,假设名称没有被索引。不过,不同的数据会出错。为了找出每次都可能不同的方法,DBMS 必须对每一列运行不同的计数查询并比较数字,这不仅仅是耸耸肩并继续下去的成本。

于 2012-07-11T15:53:41.503 回答
2

原始操作声明

我的信念是第二个更快,因为更独特的标准(姓氏)首先出现在 >where 子句中,并且记录将被更有效地消除。我认为优化器不够聪明,无法优化第一个 sql。

我猜你在创建索引时选择列的顺序混淆了这一点,你必须将更具选择性的列放在第一位而不是第二位最有选择性的列,依此类推。

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

于 2012-07-14T10:40:19.453 回答