题目 部分

在Oracle中,查询转换包含哪些类型?

答案部分

在Oracle数据库中,用户发给Oracle让其执行的目标SQL和Oracle实际执行的SQL有可能是不同的,这是因为Oracle可能会对执行的目标SQL做等价改写,即查询转换。查询转换(Query Transformation),也叫逻辑优化(Logical Optimization),又称为查询改写(Query Rewrite)或软优化,即查询转换器在逻辑上对语句做一些语义等价转换,它是Oracle在解析目标SQL的过程中的非常重要的一步。查询转换能使优化器将目标SQL改写成语义上完全等价的SQL语句但生成的执行计划效率更高。

查询转换器依据特定的方式决定是否对查询块进行转换。按照其所依赖的方式,转换技术可以分为两类:①启发式查询转换(Heuristic Query Transformation),又称为基于规则的查询转换(Rule Based Query Transformation),启发式查询转换是基于一套规则对查询进行转换,一旦满足规则所定义的条件,则对语句进行相应的转换。启发式查询转换需要从10053事件信息中查找有关查询转换的线索,并且许多跟踪记录仅能从Oracle 11g的跟踪信息中发现。②基于代价的查询转换(Cost Based Query Transformation,CBQT)。基于代价的查询转换是否对语句进行转换则取决于语义等价语句之间的代价对比,即采用代价最小的一种。大多数基于代价的查询转换可以从执行计划的概要数据中找到线索。Oracle提供了一个隐含参数“_OPTIMIZER_COST_BASED_TRANSFORMATION”用以控制是否进行基于代价的查询转换,以及如何进行基于代价的查询转换,从而限制其对资源的消耗。

Oracle中常见的查询转换分类如下图所示:

 1SYS@orclasm > SET PAGESIZE 9999 2SYS@orclasm > SET LINE 9999 3SYS@orclasm > COL NAME FORMAT A40 4SYS@orclasm > COL KSPPDESC FORMAT A50 5SYS@orclasm > COL KSPPSTVL FORMAT A20 6SYS@orclasm > SELECT A.INDX, 7  2         A.KSPPINM NAME, 8  3         A.KSPPDESC, 9  4         B.KSPPSTVL 10  5  FROM   X$KSPPI  A,11  6         X$KSPPCV B12  7  WHERE  A.INDX = B.INDX13  8  AND LOWER(A.KSPPINM) LIKE  LOWER('%&PARAMETER%');14Enter value for parameter: _OPTIMIZER_COST_BASED_TRANSFORMATION15old   8: AND LOWER(A.KSPPINM) LIKE  LOWER('%&PARAMETER%')16new   8: AND LOWER(A.KSPPINM) LIKE  LOWER('%_OPTIMIZER_COST_BASED_TRANSFORMATION%')1718      INDX NAME                                     KSPPDESC                                           KSPPSTVL19---------- ---------------------------------------- -------------------------------------------------- --------------------20      1935 _optimizer_cost_based_transformation     enables cost-based query transformation            LINEARSET PAGESIZE 9999 2SYS@orclasm > SET LINE 9999 3SYS@orclasm > COL NAME FORMAT A40 4SYS@orclasm > COL KSPPDESC FORMAT A50 5SYS@orclasm > COL KSPPSTVL FORMAT A20 6SYS@orclasm > SELECT A.INDX, 7  2         A.KSPPINM NAME, 8  3         A.KSPPDESC, 9  4         B.KSPPSTVL 10  5  FROM   X$KSPPI  A,11  6         X$KSPPCV B12  7  WHERE  A.INDX = B.INDX13  8  AND LOWER(A.KSPPINM) LIKE  LOWER('%&PARAMETER%');14Enter value for parameter: _OPTIMIZER_COST_BASED_TRANSFORMATION15old   8: AND LOWER(A.KSPPINM) LIKE  LOWER('%&PARAMETER%')16new   8: AND LOWER(A.KSPPINM) LIKE  LOWER('%_OPTIMIZER_COST_BASED_TRANSFORMATION%')1718      INDX NAME                                     KSPPDESC                                           KSPPSTVL19---------- ---------------------------------------- -------------------------------------------------- --------------------20      1935 _optimizer_cost_based_transformation     enables cost-based query transformation            LINEAR

Oracle中常见的查询转换分类如下表所示:

关于上表中的内容需要注意以下几点:

① 子查询展开通常都会提高原SQL的执行效率,因为如果原SQL不做子查询展开,那么通常情况下该子查询就会在其执行计划的最后一步才被执行,并且会走FILTER类型的执行计划,这也就意味着对于外部查询所在结果集的每一条记录,该子查询就会被执行多少次,这种执行方式的执行效率通常情况不会太高,尤其在子查询中包含两个或两个以上表连接时,此时做子查询展开后的执行效率往往会比走FILTER类型的执行计划高很多。

② 使用视图合并技术后,优化器不再单独为每个视图生成子计划,而是将视图的查询合并到整体查询中去,最终为合并和整体查询寻找到一个最优的执行计划。

③ 一般来说,如果Oracle没有做视图合并的话,那么在该SQL的执行计划中就会见到“VIEW”关键字,并且该关键字所对应的NAME列的值就是该视图的名称。

④ 由于查询转换的分类非常多,本书只对常见的重要的查询转换做介绍,其余的查询转换可以阅读其它相关的书籍。

为了方便,使用黄玮老师提供的一个存储过程sql_explain:

 1------------------------------------------------------------ 2-- 《SQL优化与调优技术详解》                             --- 3-- 文件:02_01_SQL_Explain_11g.sql                       --- 4-- 作者:黄玮                                            --- 5-- 网站:WWW.HelloDBA.COM                                --- 6-- Coyprigh (c):WWW.HelloDBA.COM 保留所有权利           --- 7-- 描述:解析和显示语句执行计划                          --- 8------------------------------------------------------------ 910/***********************************************************11** 用于11G                                                **12***********************************************************/13create or replace procedure sql_explain (stmt varchar2, 14                                         format varchar2 default 'ADVANCED', 15                                         exponly boolean default true)16------------------------------------------------------------17-- 描述:解析和显示语句执行计划                          ---18-- 来源:WWW.HelloDBA.COM                                ---19-- Coyprigh (c):WWW.HelloDBA.COM 保留所有权利           ---20--                                                       ---21-- 参数描述                                              ---22--     stmt:解析或执行的语句                            ---23--     format:执行计划输出格式,参加DBMS_XPLAN中描述    ---24--     exponly:是否仅解析                               ---25--         TRUE:仅调用EXPLAIN PLAN命令解析语句          ---26--        FALSE:执行语句后从缓存获得执行计划            ---27------------------------------------------------------------28  AUTHID CURRENT_USER 29as30  c number;31  r number;32  sqlid varchar2(100);33  childnum number;34begin35  dbms_output.enable(50000);36  if exponly then37    execute immediate 'explain plan for '||stmt;38    for xpl_rec in ( select * from table(dbms_xplan.display(null,null,format)) ) loop39        dbms_output.put_line(xpl_rec.plan_table_output);40    end loop;41  else42     c := dbms_sql.open_cursor;43     dbms_sql.parse(c,stmt,dbms_sql.native);44     r := dbms_sql.execute_and_fetch(c);45     loop46       exit when r <= 0;47       r := dbms_sql.fetch_rows(c);48     end loop;49    select distinct p.sql_id, p.child_number into sqlid, childnum 50    from v$sql_cursor sc, v$sql_plan p, v$open_cursor c, v$sqlarea q 51    where p.address=sc.PARENT_HANDLE and p.sql_id=q.sql_id and c.sql_id = q.sql_id and c.sid = SYS_CONTEXT('USERENV','SID') and q.sql_text like substr(stmt,0,30)||chr(37) and rownum<=1;52    --select distinct s.sql_id, s.child_number into sqlid, childnum from v$sql_plan s, v$sql_cursor c where s.address=c.PARENT_HANDLE and c.curno=c and rownum<=1;53    dbms_sql.close_cursor(c);54    for xpl_rec in ( select * from table(dbms_xplan.display_cursor(sqlid,childnum,format)) ) loop55        dbms_output.put_line(xpl_rec.plan_table_output);56    end loop;57  end if;58  rollback;59end;60/6162grant execute on sql_explain to public;63create or replace public synonym sql_explain for sys.sql_explain;------------------------------------------------------------ 2-- 《SQL优化与调优技术详解》                             --- 3-- 文件:02_01_SQL_Explain_11g.sql                       --- 4-- 作者:黄玮                                            --- 5-- 网站:WWW.HelloDBA.COM                                --- 6-- Coyprigh (c):WWW.HelloDBA.COM 保留所有权利           --- 7-- 描述:解析和显示语句执行计划                          --- 8------------------------------------------------------------ 910/***********************************************************11** 用于11G                                                **12***********************************************************/13create or replace procedure sql_explain (stmt varchar2, 14                                         format varchar2 default 'ADVANCED', 15                                         exponly boolean default true)16------------------------------------------------------------17-- 描述:解析和显示语句执行计划                          ---18-- 来源:WWW.HelloDBA.COM                                ---19-- Coyprigh (c):WWW.HelloDBA.COM 保留所有权利           ---20--                                                       ---21-- 参数描述                                              ---22--     stmt:解析或执行的语句                            ---23--     format:执行计划输出格式,参加DBMS_XPLAN中描述    ---24--     exponly:是否仅解析                               ---25--         TRUE:仅调用EXPLAIN PLAN命令解析语句          ---26--        FALSE:执行语句后从缓存获得执行计划            ---27------------------------------------------------------------28  AUTHID CURRENT_USER 29as30  c number;31  r number;32  sqlid varchar2(100);33  childnum number;34begin35  dbms_output.enable(50000);36  if exponly then37    execute immediate 'explain plan for '||stmt;38    for xpl_rec in ( select * from table(dbms_xplan.display(null,null,format)) ) loop39        dbms_output.put_line(xpl_rec.plan_table_output);40    end loop;41  else42     c := dbms_sql.open_cursor;43     dbms_sql.parse(c,stmt,dbms_sql.native);44     r := dbms_sql.execute_and_fetch(c);45     loop46       exit when r <= 0;47       r := dbms_sql.fetch_rows(c);48     end loop;49    select distinct p.sql_id, p.child_number into sqlid, childnum 50    from v$sql_cursor sc, v$sql_plan p, v$open_cursor c, v$sqlarea q 51    where p.address=sc.PARENT_HANDLE and p.sql_id=q.sql_id and c.sql_id = q.sql_id and c.sid = SYS_CONTEXT('USERENV','SID') and q.sql_text like substr(stmt,0,30)||chr(37) and rownum<=1;52    --select distinct s.sql_id, s.child_number into sqlid, childnum from v$sql_plan s, v$sql_cursor c where s.address=c.PARENT_HANDLE and c.curno=c and rownum<=1;53    dbms_sql.close_cursor(c);54    for xpl_rec in ( select * from table(dbms_xplan.display_cursor(sqlid,childnum,format)) ) loop55        dbms_output.put_line(xpl_rec.plan_table_output);56    end loop;57  end if;58  rollback;59end;60/6162grant execute on sql_explain to public;63create or replace public synonym sql_explain for sys.sql_explain;

本文选自《Oracle程序员面试笔试宝典》,作者:李华荣。

---------------优质麦课------------

详细内容可以添加麦老师微信或QQ私聊。

About Me:小麦苗

● 本文作者:小麦苗,只专注于数据库的技术,更注重技术的运用

● 作者博客地址:http://blog.itpub.net/26736162/abstract/1/

● 本系列题目来源于作者的学习笔记,部分整理自网络,若有侵权或不当之处还请谅解

● 版权所有,欢迎分享本文,转载请保留出处

● QQ:646634621  QQ群:618766405

● 提供OCP、OCM和高可用部分最实用的技能培训

● 题目解答若有不当之处,还望各位朋友批评指正,共同进步

DBA宝典

长按下图识别二维码或微信扫描下图二维码来关注小麦苗的微信公众号:xiaomaimiaolhr,学习最实用的数据库技术。

喜欢就点击“好看”吧

【DB笔试面试612】在Oracle中,查询转换包含哪些类型?相关推荐

  1. 【DB笔试面试164】在Oracle中,如何彻底停止expdp数据泵进程?

    [DB笔试面试164]在Oracle中,如何彻底停止expdp数据泵进程? 真题1. 如何彻底停止 expdp 进程? 答案:许多同事在使用expdp命令时,不小心按了CTRL+C组合键,然后又输入e ...

  2. 查看oracle已经锁定的表,Oracle中查询被锁定的表

    Oracle中查询被锁定的表 select --l.*,o.owner object_owner, o.object_Name,mac.status,mac.oSUSEr,mac.machine tr ...

  3. 删除oracle所有表外键,Oracle中查询、禁用、起用、删除表外键

    Oracle中查询.禁用.启用.删除表外键 1.查询所有表的外键: select table_name, constraint_name from user_constraints where con ...

  4. oracle查表字段长度,oracle中查询某张表中的字段名,字段类型,字段长度等信息...

    oracle中查询某张表中的字段名,字段类型,是否为空,字段长度等信息 --更改某张表的字段类型长度 alter table bill_info modify IDCARD VARCHAR2 (30) ...

  5. oracle未选定行大小写_关于Oracle中查询结果为未选定行

    今天在做关于Oracle查询语句的练习时,碰到这么一个题目:找出EMP表中姓名(ENAME)第三个字母是A的员工姓名.我的Scott.emp表的现有数据如下: SQL> select * fro ...

  6. oracle的int范围,oracle中int类型和number类型区别

    oracle中int类型和number类型区别 INT类型是NUMBER类型的子类型. 下面简要说明: (1)NUMBER(P,S) 该数据类型用于定义数字类型的数据,其中P表示数字的总位数(最大字节 ...

  7. oracle中行列转换总结

    oracle中行列转换 1.行列转换包括以下六种情况: 2. 列转行 2.1 UNION ALL 2.2 MODEL 2.3 COLLECTION 2.4 UNPIVOT 3. 行转列 3.1 AGG ...

  8. oracle中转换函数,Oracle中的转换函数

    Oracle中的转换函数有三个,分别为to_char(),to_date(),to_number() 1.to_char()的用法 格式化当前的日期时间 select sysdate,to_char( ...

  9. oracle 字符转整数,Oracle中字符串转换函数小数转法

    Oracle中字符串转换函数小数转法 类别:Oracle数据库   作者:码皇   来源:薛凯博客     点击: Oracle中字符串转换函数小数转法 to_char()函数的字符串转换格式归纳如下 ...

最新文章

  1. 算法---删除排序链表中的重复元素 II
  2. Python模型顶点法线修复
  3. access2003安装包百度云_阿里云服务器安装JDK与配置环境详细步骤
  4. QT添加rtmp库的时候出现问题
  5. 一文读懂Docker及其对系统管理员的重要性
  6. 学会这两招,快速突出图表重点,让老板眼前一亮
  7. 新概念英语第三册01-20课(转)
  8. uva 11419 最大匹配(最小点覆盖)
  9. 自己实现的数值到大写人民币的实现
  10. [求助] win7 x64 封装 出现 Administrator.xxxxx 的问题
  11. 网站建设php的心得和体会,网页设计心得体会
  12. 用python设计进销存_免费的进销存系统哪个好一些?
  13. 使用Petalinux定制自己的linux系统
  14. 微博视频号搬砖项目,单号月入1000+!
  15. oracle modeler 使用,Navicat Data Modeler使用教程八:图表版面下
  16. 中国天眼进入“多出成果”“出好成果”新阶段
  17. 蓝桥杯 ADV-201 VIP试题 我们的征途是星辰大海(试题解析)
  18. springBoot(6)---文件上传
  19. 七、网络安全之AAA认证技术详解
  20. PreActResNet

热门文章

  1. 抖音封禁3973个恶意炫富账号
  2. dgl-02 gcn
  3. CGU2018七彩虹游戏联盟盛典 邀你体验3A大作
  4. swiper-页面的翻页动画--渐变效果
  5. 推荐系统实践(一)----基于用户的协同过滤算法(UserCF)
  6. 是android机顶盒怎么用,网络电视机顶盒原来可以这么用,让你安卓系统流畅运行!...
  7. Mapbox GL JS实现移动端H5实时多边形(涂鸦)绘制
  8. Python版本VTK官方文档教程学习(五)
  9. 商城网店网页设计方案
  10. 手机大亨小米是否侵权引争议