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

推荐订阅源

Cyberwarzone
Cyberwarzone
S
Secure Thoughts
L
LINUX DO - 热门话题
C
Cyber Attacks, Cyber Crime and Cyber Security
C
CERT Recently Published Vulnerability Notes
P
Privacy & Cybersecurity Law Blog
A
Arctic Wolf
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
Cybersecurity and Infrastructure Security Agency CISA
大猫的无限游戏
大猫的无限游戏
U
Unit 42
Recorded Future
Recorded Future
Hacker News: Ask HN
Hacker News: Ask HN
F
Full Disclosure
Spread Privacy
Spread Privacy
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Know Your Adversary
Know Your Adversary
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
云风的 BLOG
云风的 BLOG
Stack Overflow Blog
Stack Overflow Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
F
Fortinet All Blogs
Martin Fowler
Martin Fowler
T
Threatpost
I
InfoQ
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Cloudbric
Cloudbric
L
LangChain Blog
N
Netflix TechBlog - Medium
The Register - Security
The Register - Security
S
Security @ Cisco Blogs
B
Blog
T
Threat Research - Cisco Blogs
T
The Blog of Author Tim Ferriss
The GitHub Blog
The GitHub Blog
D
DataBreaches.Net
Simon Willison's Weblog
Simon Willison's Weblog
P
Proofpoint News Feed
Microsoft Security Blog
Microsoft Security Blog
Blog — PlanetScale
Blog — PlanetScale
B
Blog RSS Feed
MongoDB | Blog
MongoDB | Blog
W
WeLiveSecurity
Forbes - Security
Forbes - Security
O
OpenAI News
C
Check Point Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
The Last Watchdog
The Last Watchdog
H
Help Net Security
SecWiki News
SecWiki News

博客园 - 兵

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

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