数据库入门指南:浅谈数据库查询优化 | 青训营

129 阅读2分钟

查询优化

如何设计一个简单查询优化器

逻辑优化:定义一些启发式的逻辑优化规则进行等价变化

物理优化:先决定访问路径,再定义一些启发式的物理优化规则决定连接顺序与连接方式

基于规则的优化

逻辑优化(代数优化)启发式规则:

  • 选择下推(谓词下推)
  • 将复杂谓词划分为多个简单谓词
  • 投影下推
  • 投影合并
  • 投影和选择(其他运算)同时进行
  • 将选择和笛卡尔积结合为一个连接算子
  • 子查询上拉,把某些子查询重写为等价的多表连接操作(子查询展开)
  • 条件化简
  • 移除未使用的字段

物理优化启发式规则:

  • 选择操作(路径选择操作)的启发式规则

    • 对于小关系(<1000行),使用全表顺序扫描,即使选择列上有索引

    • 对于大关系:

      • 对于选择条件是主码等值的查询,查询结果最多是一个元组,可以选择主码索引;
      • 对于选择条件是非主属性等值查询、非等值查询、范围查询,估算查询结果的元组数目比例较小(<10%)可以使用索引扫描方法, 否则全表顺序扫描;
    • AND连接的选择条件:

      • 如果有涉及这些属性的组合索引,优先采用组合索引扫描方法 ;
      • 如果某些属性上有一般的索引,优先采用选择率最低的一个索引;
    • OR连接的选择条件:一般使用全表顺序扫描;

  • 连接操作的启发式规则:

    • 如果两个表都已经按照连接属性排序,优先采用排序-合并连接
    • 如果前表较小,后表在连接属性上有索引,优先采用索引连接
    • 否则采用块嵌套循环或散列连接
基于代价的优化

用于物理优化,通过估计磁盘存取块数(I/O代价)、处理机时间(CPU 代价)等的代价,选择最优的物理执行计划。

维护的统计信息:

  • 对每个基本表:

    • 该表的元组总数(N)
    • 元组长度(l)
    • 占用的块数(B)
    • 占用的溢出块数(BO)
  • 对基表的每个列:

    • 该列最大值、最小值

    • 该列不同值的个数(m),和不同值的选择率(f)

      • 如果不同值的分布是均匀的,f=1/m

      • 如果不同值的分布不均匀,则每个值的选择率=具有该值的元组数/N

      基于Count-Min Sketch统计不同值的选择率(f)

      不同列的取值不是独立的,不同列的选择率直接相乘,可能导致估算不准确。

      如第一列中取值是人的选择率为1,第二列中取值是男人的选择率为0.5,

    • 该列上是否已经建立索引和索引类型(B+树索引、Hash索引)

  • 对索引(如B+树索引):

    • 索引的层数(L)
    • 索引的叶结点数(Y)
    • 不同索引值的个数,和不同索引值的选择基数(S,有S个元组具有某个索引值)

访问路径选择代价模型:

  • 全表扫描的代价估算(基本表大小为B块)

    • 全表扫描算法的代价 cost=B
    • 如果选择条件是主码=值,平均搜索代价 cost=B / 2
  • 索引扫描的代价估算(B+树,层数为L)

    • 如果选择比较条件是主码=值,需要存取从根结点到叶结点L块,再加上基本表中该元组所在的那一块, cost = L + 1
    • 如果选择比较条件是非主码=值,S是索引的选择基数(有S个元组满足条件,选择率) ,最坏的情况下,满足条件的元组可能会保存在不同的块上,此时,cost = L + S
    • 如果选择比较条件是>,>=,<,<=操作,cost = L + 访问的叶节点块

连接代价模型:

  • 嵌套循环
  • 散列连接
  • 排序-归并连接

基于代价的连接顺序搜索策略:

  • 枚举
  • DP算法

左深树:每个连接算子的右侧输入是一个关系(基本表),而不是连接后的中间结果,可以进行流水线的连接操作(子结点连接产生的记录可以马上送往父结点进行下一个连接算子,而不用等所有记录连接完成)