从 08 年开始读 inside sql server 2005, 一直到 inside sql server 2008, 似乎都是零星的去读一些片段,从没有整理过一点东西,也不知道有多少东西是自己真正知道的。所以以后读到一篇就做下笔记。
这篇是关于 Logical query processing, 逻辑查询处理过程。
select distinct | top (n) Filed1, Field2, Field3, ….Fieldn
from dbo.table1 tb1 with(Nolock)
inner join dbo.table2 tb2 with(no lock)
on tbl.Field1 = tb2.Field1
where tbl1.Field2 = 'xxx'
group by tb1.Field3
having sum(tb1.Field4) > 20
order by tb2.Field2
就自己的理解:
1) 先处理两张表的笛卡尔积,相当于一个 full outer join
2) 根据 join type, 此处是 inner join, 所以各自舍去一部分在另一张表中找不到对应值的记录
3) 舍去不符合 where 条件的记录
4) 做 group by 并且舍去不符合 having 条件的记录
5) 做 distinct, top (n)
6) 按照 tb2.Field2 排序
更深一步的介绍, From 后面还有 4 中 table 运算:
1) Join ; 2) Apply ; 3) Pivot; 4) Unpivot
1) Join 的处理流程:
- 先计算笛卡尔积;
- 舍去不符合 on 条件的记录;
- 根据 left, right outer join, 补上 outer 部分的记录
2) Apply 的处理流程:
- 先将右边的表数据,应用到左边的表里面去
- 再根据 outer apply 或者 cross apply 补上或者舍去相应的记录
还有四种 set 集合运算:union [all] , except, intersect
(1) query 1
(2) <set__operation>
(1) query 2
(3) [ Order by <order_by_list> ]
这个地方就非常重要了, 因为 query 1 , query 2 是同时进行计算的, 所以集合操作要比 in 来得快
select a.*, b.*
from dbo.table1 tbl1 with(no lock)
inner join dbo.table2 tbl2 with(no lock) on tbl1.field1 = tbl2.field1
where tbl1.field2 in('xxx','yyy') or tbl2.field2 in('xxx','yyy')
select a.*,b.*
from dbo.table1 tbl1 with(no lock)
inner join dbo.table2 tbl2 with(no lock) on tbl1.field1 = tbl2.field1
where tbl1.field2 in('xxx','yyy')
union all
select a.*,b.*
from dbo.table1 tbl1 with(no lock)
inner join dbo.table2 tbl2 with(no lock) on tbl1.field1 = tbl2.field1
where tbl2.field2 in('xxx','yyy')