看MSSQL的执行计划,学习集合操作

来源:互联网 发布:人工智能 微型无人机 编辑:程序博客网 时间:2024/05/03 21:14


  有数据表Company,跟Products表,分别是企业表跟产品表,每个企业有0个或多个产品,现在需要选出有产品的企业,

 SQL查询如下

 Select username,id From company as t 
where
 t.AttProperty='00000000000000001000' And t.Templateid=3
And
 Exists(select * from products where products.companyid=t.id)

 Select username,id From Company as t 
where
 t.AttProperty='00000000000000001000' And t.Templateid=3
And t.id in(Select companyid From Product group by companyid)

这两句的执行计划其实是一样的,如下图:


首先是表扫描,分别扫描Company表跟Products表,扫描时会根据表的主键(PK)逐行进行.

 1.扫描Company表:
 扫描Company表时将根据ID列(Company的主键列),逐行取出,判断AttProperty='00000000000000001000' 并且 Templateid=3

因为ID是主键,主键是创建聚集索引的,而聚集索引是有序的(这里ID是int类型所以按数字大小徘序),扫描完Company表的结果是一个按ID排序的记录集Rs(ID,User)

 2.扫描Products表并构建Hash表:
 同样根据Products表的主键(也是名为ID的列)逐行取出,根据每行的ComanpyID(CompanyID是对应于Company.ID的外键),建立Hash表,将从Products中取出的每一行根据CompanyID添加到Hash中来,最后我们就得到一个按CompanyID为键进行检索的Hash表了,由于扫描Products表使用的Products.ID的顺序,因此最后得到Hash表中CompanyID并不是按顺序排列的.

 3.排序Hash表

 根据CompanyID对Hash表进行排序

 4.Merge join

  Merge Join 是将两个已经排好序的表,进行匹配,逻辑上就是一个inner join, 排序好的表进行匹配时只需选择一记录数较小的表(取名为A),取其第一个记录,使用这个记录从另外一张表(取名为B)进行查找,由于是排序好的序列,可以进行二分查找,找到后,记下B表此记录的位置(设置位indexB0) 这样A表第二条记录在B表进行二分查找时,其左索引就从IndexB0开始.如果A表的某条记录在B表中无法匹配那么整个匹配就完成了.

当然在A表记录跟B表记录匹配度很高时(比方完全一样)那么做顺序查找可能效率更高,当然我无法知道MSSQL内部具体的实现,以上只是自己的猜测而已,如有不当,望多兼谅!

 可以看到SQL语句最后变成集合操作,而集合操作中又离不开,排序,查找...这些基本操作,学校出来好几年了,每天接触的多是SQL语句,今天默然发现他们早在SQL中了,-_"

原创粉丝点击