看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中了,-_"
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 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的设计模式综述