惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

U
Unit 42
N
News and Events Feed by Topic
S
Schneier on Security
G
GRAHAM CLULEY
Scott Helme
Scott Helme
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
GbyAI
GbyAI
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
C
CERT Recently Published Vulnerability Notes
T
The Exploit Database - CXSecurity.com
C
Cisco Blogs
T
The Blog of Author Tim Ferriss
Cisco Talos Blog
Cisco Talos Blog
P
Privacy & Cybersecurity Law Blog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
博客园 - 司徒正美
Blog — PlanetScale
Blog — PlanetScale
Project Zero
Project Zero
MyScale Blog
MyScale Blog
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Apple Machine Learning Research
Apple Machine Learning Research
小众软件
小众软件
The Last Watchdog
The Last Watchdog
Vercel News
Vercel News
The Cloudflare Blog
C
Check Point Blog
Help Net Security
Help Net Security
Microsoft Security Blog
Microsoft Security Blog
AI
AI
Simon Willison's Weblog
Simon Willison's Weblog
云风的 BLOG
云风的 BLOG
M
MIT News - Artificial intelligence
Stack Overflow Blog
Stack Overflow Blog
腾讯CDC
NISL@THU
NISL@THU
S
Security @ Cisco Blogs
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
S
SegmentFault 最新的问题
MongoDB | Blog
MongoDB | Blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
T
Threatpost
AWS News Blog
AWS News Blog
Cloudbric
Cloudbric
N
News and Events Feed by Topic
PCI Perspectives
PCI Perspectives
S
Securelist
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
V
Vulnerabilities – Threatpost
S
Secure Thoughts

博客园 - 兵

C#异常处理的方式 CryptoAPI与.NET数字签名类的交互问题 Firefox中Iframe的blur与focus事件问题 .NET中几种基本的线程同步方法 为什么说WinForm的控件只能在主线程中创建和调用 C#与Native C++互相访问 PHP5中的引用 Windows版的PDO太衰了 Framework里某些类型成员方法的一点疑惑 发现一个FireFox的问题 C#中COM操作(二)---接口查询 C#中COM操作(一)---实例化 非弹出式的模态对话框的背景遮罩 DOTNET事件拾遗 CSS开发辅助工具:Internet Explorer Developer Toolbar 另外一种高效地判断奇数和偶数的方法 如何利用客户端缓存对网站进行优化? 类的成员初始化顺序 一个多表查询引出的问题(1)
一个多表查询引出的问题(2)
· 2008-07-28 · via 博客园 - 兵

上次我只是把全联接的SQL语句写出来了,但是没有对其内在的过程做分析,只是简单提到了一下,内部做了四次表扫描。昨天抽空又看了一下,终于基本弄懂了里面的原理,首先我们来看一下查询计划给出的图:

右上方两次表扫描加一次嵌套循环是做的一次标准的左连接,在图中也明确的标示出来了。关键是右下方的那两次表扫描和连接。表扫描好说,就是为连接作准备的,那么,右下角的那次连接是怎么回事呢,而且从图上标示的信息可以看出,连接的类型是"Left Anti Semi Join ",一个从来都没有听说过的连接方式。网上google了一把,第一个找到的就是MS自己的站点,里面的说明如下:

Left Anti Semi Join Showplan 运算符

当第二个(底端)输入中没有匹配行时,Left Anti Semi Join 运算符返回第一个(顶端)输入中的每一行。如果 Argument 列内不存在任何联接谓词,则每行都是一个匹配行。

        怎么看都觉得有点绕口令的味道,而且连看了三遍愣是没明白是什么意思,最后根据查询的结果和前面分析的成果,再加上从词霸上查到的Semi的意思(半,不完全的),连蒙带猜的,总算是大概明白了一点。姑且妄言一下:这个Left Anti Semi Join就是一个内部的操作,有点私有函数的味道。作用就是把前面的左连接里左边表没有出现的行,而又出现在右边表里的行找出来,怎么看都有点右连接的味道。但这个semi,也就是不完全的,实在是不好理解,可能是算法优化后的结果吧。这也符合全连接的定义----把参加连接的左表和右表里各自没有的部分也都取到结果集中。剩下的串联就好理解了,就是union操作的意思。
        回过头来想想因为存在两次相对独立的连接操作,可不是嘛要进行四次表扫描。

        在这基础上我又想到了,里面那个半连接的作用既然那么像一个右联接,那么我再用一个右连接的操作来代替,然后自己再作union这一步,就是把内部执行的过程拿到外面来用SQL语句来替代。于就就又有了如下的SQL:

1select T1.A, T1.B, T1.C, T1.D, T2.E
2from T1
3    left join T2 on T1.A=T2.A and T1.B=T2.B and T1.C=T2.C
4union
5select T1.A, T1.B, T1.C, T1.D, T2.E
6from T2
7    left join T1 on T1.A=T2.A and T1.B=T2.B and T1.C=T2.C

上一章提到了,所有的右连接都可以转换为一个相等的左连接,这样得到的查询结果也完全正确。下面是这个查询的查询计划的图表:

        从这个图来看,与前一张图极为相似,都有四次表扫描,都有两次连接,都有一个串联操作。第二张图里多了一个排序的步骤,那是因为显示的union操作是要先排序的,目的是排除重复的行。两种方式的比较结果,我个人看来前一种性能可能更好点,再怎么说半连接至少不会比一个完整的左连接的开销大吧,而且在串联后还少了排序这么个开销占了47%的过程。

        一个多表查询引出的问题到此就告一个段落,基本上能想到的查询方式也都出现在这里了,以后再有什么新的发现我会接着补充在后面的。