SQL 中子句的顺序是否重要?

假设我有一个名为 的表,它有三列: 身份证姓氏名字。这些列都没有索引。 LastName 更加唯一,而 名字不那么唯一。

如果我做两次搜索:

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

我认为第二个更快,因为更独特的标准(LastName)在 where子句中排在第一位,而且记录会被更有效地删除。我认为优化器不够聪明,无法优化第一个 SQL 查询。

我的理解正确吗?

97119 次浏览

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

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

我知道 SQLServer 查询优化器将选择一个合适的索引-不管您的两个条件处于哪个顺序。我假设其他关系数据库管理系统也有类似的策略。

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

在 SQLServer 的情况下,如果您有:

  • (LastName, FirstName)上的一个索引
  • (FirstName, LastName)上的一个索引
  • (LastName)或仅 (FirstName)(或两者兼而有之)的索引

另一方面,对于 SQL Server 来说,如果你使用 SELECT *从一个表中获取 所有列,而这个表相当小,那么查询优化器很有可能只是做一个表(或者聚集索引)扫描,而不是使用索引(因为查找整个数据页来获取 所有其他列的代价太高了,非常快)。

不,所有的 RDBM 都是从分析查询开始的,并通过重新排序 where 子句对其进行优化。

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

M.

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

不要认为 SQL 会关心订单。以下内容会在 SQLServer 中生成错误:

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

如果首先执行该子句的第一部分,那么只有数值表名称将被强制转换为整数。但是,它失败了,提供了一个清楚的示例,表明 SQLServer (与其他数据库一样)不关心 WHERE 语句中子句的顺序。

就目前而言,假设名字没有被索引,这是真的。 不过,不同的数据可能会导致错误。为了找到这样做的方法,每次都可能有所不同,DBMS 必须为每一列运行一个不同的计数查询并比较数字,这将比耸耸肩继续下去要花费更多。

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

6.3.3.3规则评估顺序

...

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

复制自 给你

原始 OP 语句

我认为第二个更快,因为更唯一的条件(LastName)在 > where 子句中排在第一位,记录将更有效地被删除。我认为优化器不够聪明,无法优化第一个 sql。

我猜您在选择列顺序的同时创建索引,必须将选择性更强的列放在第一位,而不是第二位,以此类推。

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