现在的位置: 首页 > 数据库 > 正文

Oracle查询转换

2014年11月08日 数据库 ⁄ 共 1435字 暂无评论 ⁄ 阅读 1,075 次
文章目录

在语法和权限检查之后,执行计划开发之前,会有一步被称为查询转换的步骤。此时,查询会转换为一系列查询块,主要目的是确定如果改变查询的写法会不会提供更好的查询计划。查询转换能够并且可能会重写你的查询。

查询转换常用手段有视图合并、子查询解嵌套、谓语前推和使用物化视图进行查询重写

【视图合并】针对内嵌视图式子查询

视图合并是一种能将内嵌或储存式视图展开为能够独立分析或者与查询剩余部分合并成总体执行计划的独立查询块的转换。一个如select * from my_view的语句将会被改写成好像直接使用了视图源表而不是视图一样,这在子查询作为源表时常见。

视图合并常常发生在当外部查询块的谓语包括下列项时:

  • 能够在另一个查询块的索引中使用的列;
  • 能够在另一个查询块的分区截断中所使用的列;
  • 在一个联结视图中能够限制返回行数的条件;

大多数人相信视图(子查询)总是被作为独立的查询块并总有自己的子查询计划,并且会在与其他查询联结之前执行。然而,由于查询转换的存在,视图会与查询的其他部分合并,这样对性能有极大的好处。如:可能原先的查询需要对内部外部查询均全表扫描,而使用后可能内部仅需要索引扫描就可以了,这样将提升性能。

若需要强制不执行视图合并,则需要在hints中加入NO_MERGE提示,如:

SELECT /*+ NO_MERGE */ column_name FROM table_name;

另外,其他一情况也会阻止视图合并,如查询块中包含解析函数、聚合函数或集合运算,ORDER BY子句或ROWNUM等。这些情况将打破查询在核心层的执行,使其跳出核心层,然后自然就无法再与其他查询块在核心层合并了。

转换后的查询将会由优化器进行复查,视图合并和不合并的查询计划所需成本都会被评估,然后优化器就会选择成本最低的执行计划。

【子查询解嵌套】针对WHERE子句中子查询

虽然子查询解嵌套和视图合并都作用于子查询,但它们作用的位置不同。视图合并作用的子查询相当于一个内嵌视图,而子查询解嵌套作用的子查询位于WHERE子句中。之所在对WHERE子句中的子查询进行解嵌套主要是,主查询(外部查询)每执行一行都会执行一次WHERE子句中子查询,这将极不利于性能。最典型的转换就是将子查询转变为表联结。

如果一个子查询没有解嵌套,将会为它生成一个独立的子计划并作为总的执行计划的一部分按照优化执行速度的次序依次执行。

同样,我们可以使用hints中NO_UNNEST提示来强制不使用子查询解嵌套。

子查询解嵌套其实就是两种方式效率的比较,是主查询每一行数据都执行一次子查询效率高,还是将两个表联结起来生成笛卡尔积效率高。

当包含联结子查询时,子查询解嵌套转换会变得复杂一些。如,可能会生成一个内嵌视图然后跟外部查询进行联结。

【谓语前推】

谓语前推用来将谓语从一个内含查询块中应用到不可合并的查询块中,目标就是允许索引的使用或者让其他对于数据集筛选的条件在查询中能够更早的进行,这样在剩下的执行计划中所需要抓取的数据就更少了。

个人理解就是将外部查询的谓语推到内嵌视图中,这样数据源就可以减少了。

阻止谓语前推可以使用hints提示NO_PUSH_PRED,或者加入rownum子句。

【物化视图重写查询】

查询重写是一种发生在当一个查询或查询的一部分已经被保存为一个物化视图,转换器重写该查询以使用预先计算好的物化视图数据而不需要执行当前查询的转换。

声明:该笔记转载自《Oracle SQL高级编程》,仅用于个人学习,若侵犯到您的版权敬请告知!

» 声明:本站文章源于个人经验总结或书籍、互联网转载,内容仅用于个人学习,请勿转载,否则后果自负!

给我留言

留言无头像?