第一章 逻辑查询处理
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第一章 逻辑查询处理相关的知识,希望对你有一定的参考价值。
执行顺序的不同点
SQL Server与其他编程语言一个显著的不同点就在于处理逻辑的顺序。众所周知,其他的编程语言都是按照编码的顺序进行执行的,但是对于SQL而言,第一个被处理的子句是FROM,而最后一个被处理的则是SELECT子句,尽管他是在语法规范中第一个出现的。
每个步骤都会产生一个虚拟表,这个虚拟表将作为下一个步骤的输入,过程中得到的虚拟表是不可用的,只有最后一个步骤产生的虚拟表才可以被使用。
逻辑查询处理阶段
对于SQL语句的逻辑查询处理过程,可以用下图表示:
逻辑查询处理阶段简介
- FROM:对FROM子句中的前两个表执行笛卡尔积(Cartesian product)(交叉联接),生成虚拟表VT1
- ON:对VT1应用ON筛选器。只有那些使<join_condition>为真的行才被插入VT2。
- OUTER(JOIN):如 果指定了OUTER JOIN(相对于CROSS JOIN 或(INNER JOIN),保留表(preserved table:左外部联接把左表标记为保留表,右外部联接把右表标记为保留表,完全外部联接把两个表都标记为保留表)中未找到匹配的行将作为外部行添加到 VT2,生成VT3.如果FROM子句包含两个以上的表,则对上一个联接生成的结果表和下一个表重复执行步骤1到步骤3,直到处理完所有的表为止。
- WHERE:对VT3应用WHERE筛选器。只有使<where_condition>为true的行才被插入VT4.
- GROUP BY:按GROUP BY子句中的列列表对VT4中的行分组,生成VT5.
- CUBE|ROLLUP:把超组(Suppergroups)插入VT5,生成VT6.
- HAVING:对VT6应用HAVING筛选器。只有使<having_condition>为true的组才会被插入VT7.
- SELECT:处理SELECT列表,产生VT8.
- DISTINCT:将重复的行从VT8中移除,产生VT9.
- ORDER BY:将VT9中的行按ORDER BY 子句中的列列表排序,生成游标(VC10).
- TOP:从VC10的开始处选择指定数量或比例的行,生成表VT11,并返回调用者。
注:
很多人对ON和WHERE条件搞不清楚,觉得把过滤条件放在ON和放在WHERE后面都是一样的。真的一样吗?其实不是的。主要体现在以下两点:
(1)结果不同。我们说WHERE条件是对最终虚拟表的结果做过滤,而ON条件则是对当前虚拟表的结果做筛选,为下一个步骤做准备。直接影响数据的结果记录数。
(2)效率不同。我们知道,sql在表连接的时候,会产生笛卡尔积,不管采用的是INNER JOIN还是OUT LEFT(RIGHT) JOIN,他们都可能会增大数据的虚拟表,这个时候如果我们及时筛选过滤数据,那么相应的产生的虚拟表就会小。但是如果我们都把结果过滤放在WHERE条件上去筛选,那么他产生的虚拟表就可能会非常大。想一下,在10条数据中筛选数据和在10000条数据中筛选数据,哪个处理效率更高,很明显。
有时候我在优化性能的时候,第一步并不是查索引之类的。我第一步都是基于业务对SQL的写法做优化,如果还不行,再考虑其他的。很多时候,我们说查询速度很慢是因为我们的写法出了问题。所以,我一般在写语句的时候,都是能在ON中筛选数据的尽量不写在WHERE中(前提是保证数据的准确性)
三值逻辑
在SQL的逻辑表达式中一共有三种值情况:True,False和Unknown。三值逻辑是SQL语言特有的,SQL中的Unknown通常出现在NULL值的逻辑表达式中。NULL与其他值比较的结果仍然是NULL。
定值逻辑
SQL中有个“同一时间操作”的概念,就是说对于同一个操作语句中,在没有执行完成之前,所有数据都是未被修改的。举例说明:
以上数据是初始数据,下面将对其进行更新操作就可以很明显的看出“定值逻辑”。
以上是关于第一章 逻辑查询处理的主要内容,如果未能解决你的问题,请参考以下文章