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

推荐订阅源

Hacker News - Newest:
Hacker News - Newest: "LLM"
S
SegmentFault 最新的问题
The Cloudflare Blog
T
The Exploit Database - CXSecurity.com
C
CXSECURITY Database RSS Feed - CXSecurity.com
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
P
Privacy & Cybersecurity Law Blog
有赞技术团队
有赞技术团队
www.infosecurity-magazine.com
www.infosecurity-magazine.com
雷峰网
雷峰网
Google DeepMind News
Google DeepMind News
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
T
Threatpost
The Hacker News
The Hacker News
人人都是产品经理
人人都是产品经理
阮一峰的网络日志
阮一峰的网络日志
大猫的无限游戏
大猫的无限游戏
L
Lohrmann on Cybersecurity
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
W
WeLiveSecurity
T
Threat Research - Cisco Blogs
博客园 - 叶小钗
量子位
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Simon Willison's Weblog
Simon Willison's Weblog
I
Intezer
S
Secure Thoughts
V
V2EX
Apple Machine Learning Research
Apple Machine Learning Research
小众软件
小众软件
酷 壳 – CoolShell
酷 壳 – CoolShell
Microsoft Azure Blog
Microsoft Azure Blog
博客园_首页
Help Net Security
Help Net Security
爱范儿
爱范儿
C
Cybersecurity and Infrastructure Security Agency CISA
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
腾讯CDC
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
C
Check Point Blog
WordPress大学
WordPress大学
Last Week in AI
Last Week in AI
T
Tor Project blog
NISL@THU
NISL@THU
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
I
InfoQ
The Register - Security
The Register - Security
Recent Announcements
Recent Announcements
N
News and Events Feed by Topic
B
Blog RSS Feed

博客园 - 兵

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%的过程。

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