遗忘海岸

江湖程序员 -Feiph(LM战士)

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

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


  有数据表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中了,-_"

posted on   遗忘海岸  阅读(523)  评论(0编辑  收藏  举报

编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述
点击右上角即可分享
微信分享提示