在编写SQL时,会建议将选择性高(过滤数据多)的条件放到WHERE条件的前面,这是为了让查询优化器优先考虑这些条件,减少生成最优(或相对最优)的执行计划的时间,但最终的执行计划生成过滤顺序还是决定这些条件的选择性与判断bool值的容易程度

测试代码:

GO
SELECT *
INTO #T1
FROM sys.all_columns
GO
SELECT *
INTO #T2
FROM sys.all_columns
GO
SELECT *
INTO #T3
FROM sys.all_columns
GO
SET STATISTICS IO ON
SET STATISTICS TIME ON
GO
SELECT * FROM #T1 AS T1
WHERE T1.[object_id]=3
AND (SELECT COUNT(1) FROM #T2 AS T2 WHERE T2.column_id>T1.column_id)>1 SELECT * FROM #T1 AS T1
WHERE (SELECT COUNT(1) FROM #T2 AS T2 WHERE T2.column_id>T1.column_id)>1
AND T1.[object_id]=3

执行计划:

可以从查询计划看出,无论T1.[object_id]=3在何处,其计算bool值相对简单,而(SELECT COUNT(1) FROM #T2 AS T2 WHERE T2.column_id>T1.column_id)>1 需要访问其他表,因此执行优化器优先执行T1.[object_id]=3,在满足T1.[object_id]=3为ture时再坚持行是否满足(SELECT COUNT(1) FROM #T2 AS T2 WHERE T2.column_id>T1.column_id)>1。

但对于以下查询:

SELECT * FROM #T1 AS T1
WHERE (SELECT COUNT(1) FROM #T3 AS T3 WHERE T3.[object_id]>T1.[object_id])<1
AND (SELECT COUNT(1) FROM #T2 AS T2 WHERE T2.column_id>T1.column_id)>1 SELECT * FROM #T1 AS T1
WHERE (SELECT COUNT(1) FROM #T2 AS T2 WHERE T2.column_id>T1.column_id)>1
AND (SELECT COUNT(1) FROM #T3 AS T3 WHERE T3.[object_id]>T1.[object_id])<1

执行计划:

执行统计:

(25 row(s) affected)
Table 'Worktable'. Scan count 29, logical reads 36813, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table '#T3_________________________________________________________________________________________________________________00000000000C'. Scan count 4, logical reads 80, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table '#T1_________________________________________________________________________________________________________________000000000009'. Scan count 5, logical reads 59, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table '#T2_________________________________________________________________________________________________________________00000000000A'. Scan count 1, logical reads 59, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. (1 row(s) affected) SQL Server Execution Times:
CPU time = 111 ms, elapsed time = 331 ms. (25 row(s) affected)
Table '#T1_________________________________________________________________________________________________________________000000000009'. Scan count 5, logical reads 59, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 10731, logical reads 87653, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table '#T3_________________________________________________________________________________________________________________00000000000C'. Scan count 4, logical reads 236, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table '#T2_________________________________________________________________________________________________________________00000000000A'. Scan count 1, logical reads 59, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. (1 row(s) affected) SQL Server Execution Times:
CPU time = 219 ms, elapsed time = 281 ms.

条件 (SELECT COUNT(1) FROM #T2 AS T3 WHERE T3.[object_id]>T1.[object_id])<1 能过滤掉大部分数据,而(SELECT COUNT(1) FROM #T3 AS T2 WHERE T2.column_id>T1.column_id)>1不能过滤任何数据,因此如果优先执行(SELECT COUNT(1) FROM #T3 AS T2 WHERE T2.column_id>T1.column_id)>1,则会大大减少判断(SELECT COUNT(1) FROM #T2 AS T2 WHERE T2.column_id>T1.column_id)>1的次数,从而提高查询速度,但SQL Server无法推断出该结论,因此只能顺序判断WHERE 条件。

总结:虽然在很多情况下SQL Sever引擎能帮助我们判定 WHERE 条件后的执行顺序,但我们仍应该将选择性高(过滤数据多)的条件放置在 WHERE 语句中的前面,尤其对于复杂的SQL 语句,应仔细分析测试。

你比SQL SERVER 更了解你的数据!!!

执行计划--WHERE条件的先后顺序对执行计划的影响的更多相关文章

  1. 在DataTable中执行DataTable.Select("条件")返回DataTable;

    转:http://blog.csdn.net/hcf_force/article/details/7779062 1.在DataTable中执行DataTable.Select("条件&qu ...

  2. 在DataTable中执行DataTable.Select("条件")

     .在DataTable中执行DataTable.Select("条件")返回DataTable:  // <summary> // 执行DataTable中的查询返回 ...

  3. SQL 中的语法顺序与执行顺序(转)

    很多程序员都很抵触SQL.其实SQL是一整为数不多的声明性语言,只是它的运行方式完全不同于我们所熟知的命令行语言.面向对象的程序语言.甚至是函数语言. 今天大家共同学习下SQL的语法顺序与执行顺序.( ...

  4. mysql语句的书写顺序和执行顺序

    mysql语句的书写顺序和执行顺序有很大差异. 书写顺序,mysql的一般书写顺写为: select <要返回的数据列> from <表名> <join, left jo ...

  5. C++在单继承、多继承、虚继承时,构造函数、复制构造函数、赋值操作符、析构函数的执行顺序和执行内容

    一.本文目的与说明 1. 本文目的:理清在各种继承时,构造函数.复制构造函数.赋值操作符.析构函数的执行顺序和执行内容. 2. 说明:虽然复制构造函数属于构造函数的一种,有共同的地方,但是也具有一定的 ...

  6. [datatable]关于在DataTable中执行DataTable.Select("条件")返回DataTable的解决方法

    -- :09关于在DataTable中执行DataTable.Select("条件")返回DataTable的解决方法 在实际编程工程中,常常遇到这样的情况:DataTable并不 ...

  7. [日期工具分享][Shell]为特定命令依次传入顺序日期执行

    [日期工具分享][Shell]为特定命令依次传入顺序日期执行 使用方式: <本脚本文件名(必要时需要全路径)> <要执行的命令所在的文件名> <开始日期> < ...

  8. Oracle-SQL语句的语法顺序和执行顺序

    SQL语句的语法顺序和执行顺序了,我们常见的SQL语法顺序如下: SELECT DISTINCT <Top Num> <select list>FROM [left_table ...

  9. 再次聊一聊promise settimeout asycn awiat执行顺序---js执行机制 EVENT LOOP

    首先js是单线程 分为同步和异步,异步又分为(macrotask 宏任务 和 microtask微任务 ), 这图还是很清晰嘛,再来一张 总结一下,就是遇到同步先执行同步,异步的丢到一边依次排队,先排 ...

随机推荐

  1. sqlnet.ora限制客户端IP访问

    实现功能: 只允许某几个IP访问数据库服务端(白名单): $ORACLE_HOME/network/admin/sqlnet.ora 添加2个主要参数 TCP.VALIDNODE_CHECKING=y ...

  2. 常见的加密和解密算法—DES

    一.DES加密概述 DES全称为Data Encryption Standard,即数据加密标准,是一种使用密钥加密的块算法,1977年被美国联邦政府的国家标准局确定为联邦资料处理标准(FIPS),并 ...

  3. DP系列——树形DP(Codeforces543D-Road Improvement)

    一.题目链接 http://codeforces.com/problemset/problem/543/D 二.题意 给一棵树,一开始所有路都是坏的.询问,以每个节点$i$为树根,要求从树根节点到其他 ...

  4. id取模分表

    场景 1 假设按用户id分2个库 每个库分10张表. 分表策略 1.用户id%2 确定库  用户id%3确定表. 2.(用户id%(2*10))/ 10  取整确定库,(用户id%(2*10)%10确 ...

  5. yum安装nagois

    多少年前就装过了,今天再来用yum装一次,都忘干净了~~ 主监控机:CentOS 6.5 192.168.0.105被监控机:CentOS 6.5 192.168.0.107 主监控机设置:1.安装e ...

  6. 关于memcache分布式一致性hash

    consistent hashing 算法早在 1997 年就在论文 Consistent hashing and random trees 中被提出,目前在 cache 系统中应用越来越广泛: 1  ...

  7. 带入gRPC:gRPC Streaming, Client and Server

    带入gRPC:gRPC Streaming, Client and Server 原文地址:带入gRPC:gRPC Streaming, Client and Server 前言 本章节将介绍 gRP ...

  8. 39-python 字符串替换+正则

    from bs4 import BeautifulSoup import urllib.request import re moduel =re.compile('<.*?>') st = ...

  9. mysql查询赋值、修改拼接字符串

    sql中修改字符串类型的字段可以这么拼接:update tbName set UserName='abc'+UserName; 但mysql中就不行了,需要这样:update tbName set U ...

  10. WSTMart开发文档

    WSTMart开发文档页面   PC版   开源版 授权版   序言   WSTMart安装协议   WSTMart电商系统安装   商城前台安装操作指南   用户中心指南   商家中心操作指南   ...