数据库入门指南:浅谈数据库查询执行计划 | 青训营

98 阅读3分钟

关系数据库的查询处理

查询处理步骤主要包括:生成逻辑执行计划(逻辑优化),生成物理执行计划(物理优化,查询执行)

逻辑执行计划

  • 编写SQL查询语句

  • 查询分析:词法分析,语法分析(语法检查),生成抽象语法树(操作符)

  • 查询检查(语义检查):

    • 列检查:是否存在于对应的关系中?
    • 属性检查:是否有歧义?
    • 类型检查
  • 逻辑执行计划生成:生成关系代数表达式树

  • 逻辑优化:进行关系代数的等价变换,生成最优的逻辑执行计划

物理执行计划

  • 物理执行计划生成:枚举可能的物理执行计划,如访问路径的选择(全表扫描或索引扫描)、关系算子的实现
  • 物理优化:计算物理执行代价,选择最优的的物理执行计划
selection选择算子的实现
  • 全表扫描(table scan)

  • 索引扫描(index sacn)

    使用B+树,相比B树,B+树支持区间查找,并且更低

projection投影算子的实现

SQL中使用select选择列即投影,select本身不会进行去重,但在数学意义上投影需要进行去重,相当于添加了distinct关键字

去重操作的实现:

  1. 进行外部排序(包括生成初始归并段,即置换选择排序和多路归并操作)
  2. 遍历进行去重
join连接算子的实现
  • 嵌套循环(loop join)

    算法思想上,对外层循环中的每一个元组,依次顺序检查内层循环中的每一个元组的连接属性

    实际实现上,数据按块读入,是外层循环每读入一个块(块嵌套循环),依次检查内层循环中的每一个元组的连接属性,内层循环一个元组的一次检查不是与外循环的一个元组比较,而与外循环一个块中的所有元组比较。这样使得在能够检查到所有内外元组组合的情况下,减少了IO块数(假定外循环m块,内循环n块,则IO块数为mn,而不是外循环元组数n,显然一个块中有多个元组)

  • 索引连接(index join)

    对表A join 表B,对A中的每一个元组,索引查找表B的连接属性(显然适合A是小表,B是大表的情况)

    与嵌套循环相比,内层循环遍历查找的功能由表的索引功能完成,使用索引查找,而不是遍历查找,也叫索引嵌套循环。

  • 归并-连接算法(merge join)

    适用于A B两个表都按连接属性排好序的等值连接情况,如果无序则需先进行排序;

    合并方式和归并排序的归并操作类似,当遇到两个序列的连接值相同时进行连接,这样两个表都只需扫描一遍即可

  • 散列连接(hash join)

    对表A join 表B,使用同一个散列函数,按照连接属性的值,将表A和表B的元组分散到桶当中,将映射到同一个桶中的表A元组和表B元组进行判断并进行等值连接(由于哈希冲突的存在,同一个桶中的表A元组和表B元组在连接属性上也可能不相等)

    基于这种思想,完全可以编写一个MapReduce程序完成关系表的自然连接,map输出的key为连接属性上的值。

distinct去重的实现
  • 排序去重
  • 哈希去重
group聚集算子的实现
  • 排序聚集
  • 哈希聚集