Note09- 查询优化
设有如下两个关系:
有如下 SQL 语句:
SELECT DISTINCT S.SN
FROM S,SC
WHERE S.S#=SC.S# AND SC.C#='C2'
我们可以将它转换为多种等价的关系代数表达式,且执行效率很可能有较大差别
- 计算
和 的笛卡尔积 - 按照选择条件,选择满足要求的元组
- 投影输出
- 计算
- 计算自然连接
- 读取中间文件快
- 投影输出
- 对
作选择运算 - 读取
表,把读入的 元组和内存中的 元组作连接 - 投影输出
- 对
关系代数等价转换规则
- 选择串接律。
- 选择交换律。
- 投影串接律。
,其中,
- 选择投影交换律。
,假定 只涉及 中的属性
- 连接和笛卡尔乘积的交换律。
- 集合操作的交换律。
- 连接、笛卡尔乘积和集合操作的结合律
- 选择、连接和笛卡尔乘积的分配律。
- 投影、连接和笛卡尔乘积的分配律。
- 选择与集合操作的分配律
- 投影与集合操作的分配律
表达式结果大小的估计
定义如下符号:
:关系 的元组数 :包含关系 中元组的磁盘块数 :关系 中每个元组的字节数 :关系 的块因子,一个磁盘块能容纳 中元组的个数 :关系 中属性 中出现的非重复值的个数
当
-
投影
- 估计值为
- 估计值为
-
选择
- 估计值为
- 估计值为
-
选择
- 如果
,则估计值为 0 - 如果
,则估计值为 - 否则,估计值为
- 如果
-
合取
- 对于每个
,估计选择大小为 ,则为
- 对于每个
-
析取
-
取反
- 在无空值的情况下,估计值为
- 在有空值得请开给你下,估计值为
- 在无空值的情况下,估计值为
-
笛卡尔积
- 元组个数
,每个元组占 个字节
- 元组个数
-
自然连接
和 - 若
为空,则类似于笛卡尔积的结果 - 若
为 的码,则可知 的一个元组至多与 的一个元组相连接,因此自然连接结果的元组数小于等于 ,若 构成 中参照 的外码,则自然连接结果等于 ,反之亦然 - 若
既不是 的码也不是 的码,则
- 若
-
聚集
-
集合运算
- 和合取、析取、取反的估计方法一样
-
外连接(结果上界)
左外连接 : 与 自然连接的大小估计值 右外连接 : 与 自然连接的大小估计值 全外连接 : 与 自然连接的大小估计值
启发式关系代数优化算法
- 规则 1:选择和投影操作尽早执行
- 规则 2:把某些选择操作与笛卡尔乘积相结合,形成一个连接操作
- 规则 3:同时执行相同关系上的多个选择和投影操作
- 规则 4:把投影操作与连接操作结合起来执行
- 规则 5:提取公共表达式
具体算法如下:
- 把形如
的选择表达式变成串接形式 - 对每个选择,依据定理 L4 至 L9 尽可能把它移至树的底部
- 对每个投影,依据定理 L3,L7,L10 和 L5,尽可能把它移至树的底部
- 依据定理 L4 至 L5 把串接的选择和投影组合为单个选择、单个投影,或者一选择后跟一个投影
- 对修改后的语法树,将其内结点按以下方式分组:
- 每个二元运算结点(积、并、差、连接等)和其所有一元运算直接祖先结点放在一组
- 对于其后代结点,若后代结点是一串一元运算且以树叶为终点,则将这些一元运算结点放在该组中
- 若该二元运算结点是笛卡儿积,且其后代结点不能和它组合成等连接,则不能将后代结点归入该组
- 产生一个程序:它以每组结点为一步,但后代组先执行。
举例
查询:查出 1978 年 1 月 1 日前被借出的所有书的书名
SELECT Title FROM XLOANS WHERE Data <= 1/1/78
XLOANS 视图为
CREATE VIEW XLOANS as SELECT *
FROM LOANS, BORROWERS,
WHERE BORROWERS.CARD_NO=LOANS.CARD_NO AND BOOKS.LC_NO=LOANS.LC_NO
转换成关系代数表达式:
首先,我们要将选择表达式变成串接的形式,然后对于每个选择,尽可能把它移至树的底部
对每个投影,尽可能移动到底部,由
类似处理 BORRWERS 和 LOANS 的投影:
然后分组: