知识卡片
代数优化五条实践原则
内容
面对众多关系代数等价规则,实际做代数优化时不需要穷举所有规则的 应用可能,而是遵循五条经过验证的实践原则,每条都对应[[代数优化的 实证价值:操作顺序差十万倍代价]]里揭示的某种代价放大/压缩机制。 第一,选择运算尽量先做:这是最基本的一条,选择做得越早,参与后续 运算的中间数据量越少,代价可能因此下降几个数量级。第二,投影运算 与选择运算同时做:如果同一个关系上既要投影又要选择,合并处理能 避免对这个关系扫描两遍。第三,尽量把投影运算与相邻的双目运算(如 连接)结合:不要仅仅为了去掉某些不需要的属性就单独扫描一遍关系, 应该在连接的同时顺带完成投影。第四,尽量把选择运算和笛卡儿积结合 成连接运算:笛卡儿积本身代价高昂(结果规模是两个关系规模的乘积), 而”先做笛卡儿积、再用选择筛出满足连接条件的部分”和”直接用连接运算” 在语义上等价,但连接运算有专门的高效算法(见[[连接运算三大类算法 的适用条件]]),不需要真的生成完整笛卡儿积再筛选。第五,尽量查找 并提取公共子表达式:如果查询里同一段子表达式被用到多次,只计算 一次并存下中间结果,比重复计算多次的代价更低。这五条原则的共同 逻辑是:尽早把数据规模压小,尽量避免真的生成规模等于笛卡儿积的 中间结果,尽量复用已经算过的结果。
结构图:
flowchart TD
A[代数优化五条原则] --> B[选择运算尽量先做<br/>最基本, 代价可下降几个数量级]
A --> C[投影与选择同时做<br/>避免同一关系扫描两遍]
A --> D[投影与相邻双目运算结合<br/>不为去属性单独扫描]
A --> E[选择+笛卡儿积合并为连接<br/>避免真正生成笛卡儿积]
A --> F[提取公共子表达式<br/>只计算一次, 复用结果]
参考来源
- 位置:《数据库原理(微课版)》第10章《查询处理与优化》10.3.2节"查询
的代数优化方法"(源文件:_epub-src/index_split_006.html)
- 结论依据:原文明确"选择运算尽量先做……选择运算越早做,中间结果
越少,甚至可以使查询代价整体上下降几个数量级……尽量把投影运算与
其相邻的双目运算结合,避免仅因为去掉某些属性而扫描一遍关系……
尽量将选择运算与笛卡儿积结合成连接运算。因为笛卡儿积运算的代价大,
而连接运算可以通过高效算法降低查询代价……尽量查找并提取公共子
表达式",因此可以推出五条原则的具体内容与共同逻辑。
- 原始内容:选择运算尽量先做。这条规则是最基本的一条,因为选择运算
越早做,中间结果越少,甚至可以使查询代价整体上下降几个数量级……
尽量将选择运算与笛卡儿积结合成连接运算。