【DB笔试面试612】在Oracle中,查询转换包含哪些类型?
作者:互联网
在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 B
12 7 WHERE A.INDX = B.INDX
13 8 AND LOWER(A.KSPPINM) LIKE LOWER('%&PARAMETER%');
14Enter value for parameter: _OPTIMIZER_COST_BASED_TRANSFORMATION
15old 8: AND LOWER(A.KSPPINM) LIKE LOWER('%&PARAMETER%')
16new 8: AND LOWER(A.KSPPINM) LIKE LOWER('%_OPTIMIZER_COST_BASED_TRANSFORMATION%')
17
18 INDX NAME KSPPDESC KSPPSTVL
19---------- ---------------------------------------- -------------------------------------------------- --------------------
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------------------------------------------------------------
9
10/***********************************************************
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
29as
30 c number;
31 r number;
32 sqlid varchar2(100);
33 childnum number;
34begin
35 dbms_output.enable(50000);
36 if exponly then
37 execute immediate 'explain plan for '||stmt;
38 for xpl_rec in ( select * from table(dbms_xplan.display(null,null,format)) ) loop
39 dbms_output.put_line(xpl_rec.plan_table_output);
40 end loop;
41 else
42 c := dbms_sql.open_cursor;
43 dbms_sql.parse(c,stmt,dbms_sql.native);
44 r := dbms_sql.execute_and_fetch(c);
45 loop
46 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)) ) loop
55 dbms_output.put_line(xpl_rec.plan_table_output);
56 end loop;
57 end if;
58 rollback;
59end;
60/
61
62grant execute on sql_explain to public;
63create or replace public synonym sql_explain for sys.sql_explain;
本文选自《Oracle程序员面试笔试宝典》,作者:李华荣。
---------------优质麦课------------
详细内容可以添加麦老师微信或QQ私聊。
● 本文作者:小麦苗,只专注于数据库的技术,更注重技术的运用
● 作者博客地址:http://blog.itpub.net/26736162/abstract/1/
● 本系列题目来源于作者的学习笔记,部分整理自网络,若有侵权或不当之处还请谅解
● 版权所有,欢迎分享本文,转载请保留出处
● QQ:646634621 QQ群:618766405
● 提供OCP、OCM和高可用部分最实用的技能培训
● 题目解答若有不当之处,还望各位朋友批评指正,共同进步
长按下图识别二维码或微信扫描下图二维码来关注小麦苗的微信公众号:xiaomaimiaolhr,学习最实用的数据库技术。
本文分享自微信公众号 - DB宝(lhrdba)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。
标签:转换,612,DB,查询,---,--,sql,Oracle 来源: https://blog.51cto.com/lhrbest/2709624