首页 > 代码库 > 简单视图合并
简单视图合并
1 启发式查询转换
所有的启发式查询转换都是基于一套优化器内建的规则。在查询转换阶段,转换器会逐个针对这些规则对查询进行检查,确定其是否满足转换规则,一旦满足,转换器就对其进行转换。
1.1 简单视图合并
我们知道,视图(View)的实质就是一条查询语句。在解析阶段,语句中的每个视图都会被展开至一个查询块中。如果未做视图合并,优化器则会单独分析每个视图,并为定义视图的查询语句生成一个视图子计划。然后再分析整个查询的其他部分,并生成执行计划。在这种情况下,由于视图的执行计划和整体执行计划不是同时统一做评估的,因此其最终计划可能不是最优的执行计划。
使用视图合并技术后,优化器不再单独为每个视图生成子计划,而是将视图的查询合并到整体查询中去,最终为合并和整体查询寻找到一个最优的执行计划。要将视图查询合并到主查询中去,优化器会用视图所依赖的表的名字替换视图名字,并将视图查询中的WHERE条件合并到主查询的WHERE条件中去。
根据子查询在主查询中的位置以及其与主查询中所引用的表的关系的不同,子查询分为以下几种:
标量子查询(Scalar Subquery):出现在SELECT列表中的子查询称为标量子查询;
内联视图(Inline View):出现在FROM子句中的视图称为内联视图;
嵌套子查询(Nested Subquery):出现在WHERE子句中的子查询称为嵌套子查询;
互关联子查询(Correlated Subquery):如果嵌套子查询是主查询WHERE条件的逻辑表达式的一部分(非IN、EXISTS子查询),并且嵌套子查询的查询条件中还包含主查询中表的字段,那么这样的子查询又称为互关联子查询。
提示:是否进行视图合并,可以由优化器参数_simple_view_merging或者提示MERGE/NO_MERGE控制,默认为TRUE。
视图合并又可以分为简单视图合并与复杂视图合并:
对于“选择—投影—关联”(Select-Project-Join)的视图的合并称为简单视图合并(Simple View Merge),通常这种合并属于启发式查询转换,即只要视图合并特性被开启(_simple_view_merging=TRUE)都能被合并;
对于含有DISTINCT、GROUP BY的视图的合并称为复杂视图合并(Complex View Merge),复杂视图合并通常属于基于代价的查询转换,最终是否合并取决于代价大小,因此我们将复杂视图合并放在下一节介绍。
当存在以下情况时,不能进行视图合并:
含有集合操作(UNION, UNION ALL, INTERSECT, MINUS)、聚集函数(AVG, COUNT, MAX, MIN, SUM等)、ROWNUM和CONNECT BY的视图则不能被合并;
如果主查询语句中含有CURSOR表达式,则查询中的任何视图都不能被合并。