开发者社区 问答 正文

sql问题之where条件的优先级

sql问题之where条件的优先级

如果我一个查询里边
过滤,where 子句
用了datetime > 2015-01 and sex = 1

比如数据有100万
肯定是先用datetime过滤要滤到1大批数据了

假如datetime 过滤后,有10万数据符合条件

先用sex,有50万数据符合条件.

我肯定是希望先用datetime来过滤,然后再用sex过滤.

还是我根本不用考虑,系统底层无差别?

我在用sql server.

展开
收起
a123456678 2016-07-01 15:50:38 2989 分享 版权
1 条回答
写回答
取消 提交回答
  • 在 SQL Server 中,WHERE 子句的表达式先后顺序没有影响。根据运算符的优先级进行运算,相同优先级的运算符两侧的表达式根据评估的代价多寡来运算,先运算代价小的,后运算代价大的。

    如果楼主(或楼主所在的项目)对性能比较敏感,可以通过优化查询策略(如利用索引等)来「引导」Sql Server 的优化器先运算代价小的、后运算代价大的表达式。

    All-At-Once Operation(同时操作)概念
    SQL 支持这种概念,这意味着统一逻辑查询处理阶段中出现的所有表达式都是同时进行计算的。这一块我们可以分别讲讲 SELECT 子句和 WHERE 子句。

    SELECT 子句
    以下代码是错误的:

    SELECT
    orderid,
    YEAR(orderdate) AS orderyear,
    orderyear + 1 AS nextyear
    FROM [DemoDb].dbo.[Orders]
    原因是:由于 SELECT 子句中所有列名逻辑上没有先后顺序的,所有表达式都是在同一时刻进行的

    WHERE 子句
    接下来就是回应本回复最早前那句话的问题了,关于 WHERE 子句,我们首先来看这么一个例子:

    SELECT col1, col2
    FROM [DemoDb].dbo.[T1]
    WHERE col1 <> 0 AND col2 / col1 > 2
    假设楼主想找 col2 / col1 值大于 2 的所有 col1 和 col2 集,但又担心除数为零出现错误,所以在之前加上了 col1 <> 0。问题在于,这是否有用?

    假设咱们的数据库足够机智,通过「短路求值」的原则来执行,放 col1 为 0 时不再去判断 col2 / col1 > 2,那么貌似不会出错,但是……

    我们不能忘记 All-At-Once Operation 这个概念,这个概念被写进了 ANSI SQL 中,所以微软对 ANSI SQL 的实现(Microsoft SQL Server)可以按照它喜欢的任意顺序来自由处理 WHERE 子句中的表达式(其中包括自由选择支持「短路求值」),这种选择的「喜好」的唯一依据是性能,或者说代价,也就是说先计算需要付出较小代价的表达式,然后计算较大代价的表达式。如果 SQL Server 决定先计算 col2 / col1 > 2 这个表达式,那么可能会因为除数为零而出现错误,进而查询失败。

    总结
    楼主不必关心 WHERE 子句的表达式先后顺序是否会对查询性能产生影响,优化器会根据评估自动对其进行先后运算,其依据是运算符的优先级和评估的性能代价。

    楼主可以尝试通过建立索引以减少对 IO 的需要,以此来提高性能。同时决定性能的要素很多,包括你的表的设计、硬件、网络等,更加具体的信息建议楼主阅读 《Microsoft SQL Server 2008 技术内幕:T-SQL 查询》,能系统地了解性能相关的信息。

    2019-07-17 19:50:10
    赞同 展开评论