RDBMS查询处理阶段:
实现查询操作的算法实例
1.选择操作的实现
[例1]Select * from student where <条件表达式> ;
考虑<条件表达式>的几种情况:
C1:无条件;
C2:Sno='200215121';
C3:Sage>20;
C4:Sdept='CS' AND Sage>20;
选择操作典型实现方法:
1. 简单的全表扫描方法
对查询的基本表顺序扫描,逐一检查每个元组是否满足选择条件,把满足条件的元组作为结果输出适合小表,不适合大表
2. 索引(或散列)扫描方法
适合选择条件中的属性上有索引(例如B+树索引或Hash索引) ,通过索引先找到满足条件的元组主码或元组指针,再通过元组指针直接在查询的基本表中找到元组
[例1-C2] 以C2为例,Sno=‘200215121’,并且Sno上有索引(或Sno是散列码)
使用索引(或散列)得到Sno为‘200215121’ 元组的指针,通过元组指针在student表中检索到该学生
[例1-C3] 以C3为例,Sage>20,并且Sage 上有B+树索引
使用B+树索引找到Sage=20的索引项,以此为入口点在B+树的顺序集上得到Sage>20的所有元组指针
通过这些元组指针到student表中检索到所有年龄大于20的学生。
[例1-C4] 以C4为例,Sdept=‘CS’ AND Sage>20,如果Sdept和Sage上都有索引:
算法一:分别用上面两种方法分别找到Sdept=‘CS’的一组元组指针和Sage>20的另一组元组指针
求这2组指针的交集 到student表中检索 得到计算机系年龄大于20的学生
算法二:找到Sdept=‘CS’的一组元组指针,
通过这些元组指针到student表中检索 对得到的元组检查另一些选择条件(如Sage>20)是否满足
把满足条件的元组作为结果输出。
2.连接操作的实现
[例2] SELECT * FROM Student,SC
WHERE Student.Sno=SC.Sno
1. 嵌套循环方法(nested loop)
对外层循环(Student)的每一个元组(s),检索内层循环(SC)中的每一个元组(sc)
检查这两个元组在连接属性(sno)上是否相等
如果满足连接条件,则串接后作为结果输出,直到外层循环表中的元组处理完为止
2. 排序-合并方法(sort-merge join 或merge join)
Ø如果连接的表没有排好序,先对Student表和SC表按连接属性Sno排序
Ø取Student表中第一个Sno,依次扫描SC表中具有相同Sno的元组
Ø当扫描到Sno不相同的第一个SC元组时,返回Student表扫描它的下一个元组,再扫描SC表中具有相同Sno的元组,把它们连接起来
Ø重复上述步骤直到Student 表扫描完
vStudent表和SC表都只要扫描一遍
v如果2个表原来无序,执行时间要加上对两个表的排序时间
v对于2个大表,先排序后使用sort-merge join方法执行连接,总的时间一般仍会大大减少
3. 索引连接(index join)方法
① 在SC表上建立属性Sno的索引,如果原来没有该索引
② 对Student中每一个元组,由Sno值通过SC的索引查找相应的SC元组
③ 把这些SC元组和Student元组连接起来
循环执行②③,直到Student表中的元组处理完为止
4. Hash Join方法
把连接属性作为hash码,用同一个hash函数把R和S中的元组散列到同一个hash文件中 .
hash join算法前提:假设两个表中较小的表在第一阶段后可以完全放入内存的hash桶中
v划分阶段(partitioning phase):
对包含较少元组的表(比如R)进行一遍处理
把它的元组按hash函数分散到hash表的桶中
v试探阶段(probing phase):也称为连接阶段(join phase)
对另一个表(S)进行一遍处理
把S的元组散列到适当的hash桶中
把元组与桶中所有来自R并与之相匹配的元组连接起来