您的位置:首页 > 数据库

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

2008-12-25 09:26 155 查看
  有数据表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中了,-_"
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: