关于嵌套查询和连接查询的效率问题
这⼏天给部门写讲稿,总是讲到连接和嵌套的问题,连接好像⼤多数⽤得多⼀点,感觉和我们的思维很接近,不容易接受嵌套的思路,但实际上,在相同的问题上,我们⽤嵌套,会获得⽐连接⾼⼗倍的效率。
下⾯我们来做⼀个例⼦说明  blog上贴图真不舒服,就把图都省略了。。。。
现在设教学数据库中有三个基本表
S (S#,Sname,Age,Sex)    学号,姓名,年龄,性别
SC (S#,C#,Grade)      学号 ,课程号,分数
C(C#,Cname,Teacher)    课程号,课程名,任课⽼师
要求:要求检索出学习课程号为C2的学⽣学号与姓名
下⾯我们⽤连接和嵌套⼆种⽅法并执⾏并跟踪,看它们的执⾏效果,
⽅法⼀:连接查询
SELECT S.S#,SNAME
FROM S,SC
WHERE S.S# = SC.S#  AND  C# = 'C2'
我们来分析⽅法⼀的查询过程:先对s和sc做笛卡尔积,得到⼀个S的⾏数+SC⾏数的⼆维表,然后对⼆该表进⾏逐⾏扫描,本例中也就是对⼀个9+21 =30 ⾏的表进⾏扫描。从查询分析器我们看到,在数据库中的逻辑处理是Inner join ,实际上数据库进⾏了哈希匹配的操作,在进⾏这项操作的时候预计成本达到0.017847(这个cpu成本究竟指什么我还不是很清楚,但可以肯定的是它是个资源消耗指标),预计⼦树成本为0.0931
join和in哪个查询更快
⽅法⼆:嵌套查询
SELECT S#,SNAME
FROM S
WHERE S# IN (SELECT S# FROM SC WHERE C# = 'C2')
我们来分析⽅法⼆的查询过程,数据库先检索选修出课程为C2的学⽣,得到⼀个6⾏的⼆维表,再对该6⾏数据和S表进⾏扫描检索。
从上图可以看出进⾏物理上的嵌套循环操作,cpu成本仅需要0.00038,执⾏成本仅需要0.000131,预计⼦树成本减⼩到0.0769。
从以上分析可以看出,⽅法⼆和⽅法⼀同样可以达到检索出选修了课程C2的学⽣姓名和学号,但是⽅法⼆消耗资源要要精减得多,速度要快,成本⽐⽅法降低⾮常多。因为⽅法⼆先进⾏⼦结果选择操作,再对⼦结果进⾏查询,这样对于时间和空间的开销都要⼩得多,所以我们可以看到,连接的消耗是很⼤的。
从这个例⼦,我们重申上节课提出的优化策略的第⼀条:
在关系代数表达式中尽可能早地执⾏选择操作
题外:此题还可以有⼆种写法:
select s#,sname
from s
where  exists (select * from sc where sc.s# = s.s# and c# = 'c2')
Select s#,sname
from s
where ‘c2’ in (select c# from sc where s# = s.s#)
这⼆种写法的效率和⽅法⼆是⼀模⼀样的,在sql内部执⾏的时候,它们会被优化成⽅法⼆的语句去执⾏。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。