数据库-查询优化器
数据库都会对sql做查询优化处理,这个过程是怎样的呢?
首先,查询优化器使用等价规则系统的产生与给定表达式等价的表达式。概念上,只要表达式中有任何则表达式与等价规则的某一边想匹配就产生一个新的表达式。为了减少空间需求,大多优化器都会让有公共子表达式的表达式指向共享子表达式。此外,若把执行代价估计考虑进去,可以避免检查某些表达式。
关系代数的等价规则见:http://jsjedu.hxu.edu.cn/sjkyl/4/4.2.4.htm
产生表达式后,需要定义每个运算使用什么算法以及如何协调各运算执行。选择执行计划的方法之一是简单的为每个运算选择一个代价最小的算法。但是,考虑到总体,例如尽管在给定层次上归并连接比散列连接代价大,但它却产生有序的输出,从而使以后的运算代价变小。实际的查询优化器是结合了一下两种优化方法:
基于代价的优化
通过使用等价规则为给定的查询语句产生一系列查询执行计划、并选择其中代价最小的一个。一般而言,对于n个关系,有(2(n-1))!/((n-1)!个不同的连接顺序。实际上,不用检查所有的连接,而是要为n个给定关系集合的每个子集找出最佳连接顺序,还要为每个子集、该子集连接结果的每个感兴趣的排序顺序找出最佳连接顺序。n个关系的子集总数是2^n,即约有2^n个连接表达式需要存储,用于处理排序顺序的算法的时间代价韵味3^n。
启发式优化
许多系统启发式方法减少基于代价的方式中可选择的方案数。启发式优化器不验证采用某规则转换后代价是否减少。规则1:尽早执行选择运算。规则2:尽早执行投影运算。启发式算法典型步骤:
1、将何去选择分解为单个选择运算的序列。
2、把选择运算在查询树中下推到最早可能执行的地方。
3、确定哪些选择运算与连接运算将产生最小的关系。使用连接操作的结合律,使得限制比较严格的选择运算的叶节点首先执行。
4、将其后跟有选择条件的笛卡尔积运算替换成连接运算。
5、将投影属性加以分解并在查询树上尽可能往下推。
6、识别那些可用流水方式执行器运算的子树,采用流水线执行之。
实例:
SystemR优化器:仅考虑有操作数是原始关系的连接顺序,方便用于流水线计算。
Sybase优化器:对使用辅助索引进行扫描,考虑包含该元组的页在缓冲区中的概率。
Oracle7:使内层关系上没有索引的嵌套循环连接个数及排序归并连接个数最小。