oracle 理解执行计划详解程序员
·BUFFER SORT是BUFFER却不是SORT
用AUTOTRACE查看执行的计划的同学常问到执行计划里的BUFFER SORT是什么意思,这里为什么要排序呢?
BUFFER SORT不是一种排序,而是一种临时表的创建方式。
BUFFER是执行计划想要表达的重点,是其操作: 在内存中存放一张临时表。
SORT修饰BUFFER,表示具体在内存的什么地方存放临时表: 在PGA的SQL工作区里的排序区。
至少有一种方法可以说服对此表示怀疑的人们,就是查询V$SQL_PLAN_STATISTICS_ALL.PROJECTION字段。
将STATISTICS_LEVEL设置为ALL先,然后执行真-排序命令,比如:select hire_date,salary from hr.employees order by hire_date
然后查看其V$SQL_PLAN_STATISTICS_ALL.PROJECTION字段:
[email protected]//scripts select projection from v$sql_plan_statistics_all where sql_id=(select sql_id from v$sql where sql_text= select hire_date,salary from hr.employees order by hire_date ) and operation= SORT and options= ORDER BY
PROJECTION
(#keys=1) HIRE_DATE [DATE,7], SALARY [NUMBER,22]
1 row selected.
其中开头的#keys表示返回的结果中排序的字段数量。
再执行一句真-排序命令:select hire_date,salary from hr.employees order by salary,hire_date
然后查看其V$SQL_PLAN_STATISTICS_ALL.PROJECTION字段,#keys因该为2:
[email protected]//scripts select projection from v$sql_plan_statistics_all where sql_id=(select sql_id from v$sql where sql_text= select hire_date,salary from hr.employees order by salary,hire_date ) and operation= SORT and options= ORDER BY
PROJECTION
(#keys=2) SALARY [NUMBER,22], HIRE_DATE [DATE,7]
1 row selected.
看,这回2了吧,北方的同学不要笑,请忍住。
来看看我们萌萌的BUFFER SORT的表现吧~
执行下面这个查询,它使用了所谓的BUFFER SORT:
select ch.channel_class,c.cust_city,sum(s.amount_sold) sales_amount
from sh.sales s,sh.customers c,sh.channels ch
where s.cust_id=c.cust_id and s.channel_id=ch.channel_id and
c.cust_state_province= CA and
ch.channel_desc= Internet
group by ch.channel_class,c.cust_city
附上其执行计划,Id为5的Operation是BUFFER SORT:
execution Plan
-
Plan hash value: 3047021169
-
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
-
| 0 | SELECT STATEMENT | | 133 | 7980 | 902 (2)| 00:00:11 | | |
| 1 | HASH GROUP BY | | 133 | 7980 | 902 (2)| 00:00:11 | | |
|* 2 | HASH JOIN | | 12456 | 729K| 901 (2)| 00:00:11 | | |
| 3 | MERGE JOIN CARTESIAN| | 383 | 18001 | 408 (1)| 00:00:05 | | |
|* 4 | TABLE ACCESS FULL | CHANNELS | 1 | 21 | 3 (0)| 00:00:01 | | |
| 5 | BUFFER SORT | | 383 | 9958 | 405 (1)| 00:00:05 | | |
|* 6 | TABLE ACCESS FULL | CUSTOMERS | 383 | 9958 | 405 (1)| 00:00:05 | | |
| 7 | PARTITION RANGE ALL | | 918K| 11M| 489 (2)| 00:00:06 | 1 | 28 |
| 8 | TABLE ACCESS FULL | SALES | 918K| 11M| 489 (2)| 00:00:06 | 1 | 28 |
-
查看其V$SQL_PLAN_STATISTICS_ALL.PROJECTION字段:
[email protected]//scripts select distinct projection from v$sql_plan_statistics_all where sql_id in (select distinct sql_id from v$sql where sql_text like %where s.cust_id=c.cust_id and s.channel_id=ch.channel_id and% ) and operation= BUFFER and options= SORT
PROJECTION
(#keys=0) C . CUST_ID [NUMBER,22], C . CUST_CITY [VARCHAR2,30]
1 row selected.
结果#keys等于0,是0啊 0意味着该操作根据0个字段排序,那就是没有排序咯。
同样显示SORT但是不SORT打着左灯向右转的还有著名的SORT AGGREGATE。
·RIGHT SEMI
HASH JOIN RIGHT SEMI是exisit判式的一个特殊操作。HASH JOIN是Oracle优化两个表(其中一个数据表数据量较小,而另一个数据量较大)连接的一种方式。因为在整个查询中,子查询的外部表 business.accintvoucher a (视作左表)与内部表 business.accmainvoucher (视作右表)实际进行的是连接操作,这不可避免的会产生重复记录。Oracle利用SEMI策略来防 止这一情况,即针对 外部表business.accmainvoucher a的中每一行,一旦与内部表business.accmainvoucher 中的某条记录 匹配成功,将立即返回。
Oracle官方文档对SEMI这种策略进行了定义。
A semi-join returns rows that match an EXISTS subquery without duplicating rows from the left side of the predicate when multiple rows on the right side satisfy the criteria of the subquery。
也就是说,SEMI连接是exists子查询的一种特殊处理方式,semi join最主要的使用场景就是解决exist in。
7151.html
服务器部署程序员系统优化网站设置运维相关文章
- ORA-01380: Instance string (thread string) has less than two string block size log files ORACLE 报错 故障修复 远程处理
- Oracle执行过程:有效优化你的查询(oracle执行过程)
- Oracle执行日志分析:挖掘系统性能秘密(oracle执行日志)
- 解决Oracle控制文件修改问题(oracle修改控制文件)
- 执行利用Oracle实现高效的多语句执行(oracle多语句)
- Oracle版本升级:从低到高提升效率(oracle版本修改)
- 初探Oracle触发器:进阶类型技巧(oracle触发器类型)
- 利用Oracle触发器实现自动化操作(oracle触发器类型)
- Oracle刘相兵:成就传奇的程序员(oracle刘相兵)
- 深入剖析Oracle触发器类型(oracle触发器类型)
- Oracle如何实现动态执行SQL语句?(oracle动态执行)
- 优化 优化Oracle执行效率: 7个重要步骤(oracle执行效率)
- 突破Oracle认证考试:全面掌握试题(oracle认证考试试题)
- 账户Oracle创建DBA账户:一步步指南(oracle创建dba)
- Oracle函数 大小写转换实现详解(oracle大小写函数)
- 深入剖析Oracle执行计划:从概念到实战详解(oracle执行计划详解)
- 移动技术改变:以Oracle为引领(移动表oracle)
- 「Oracle如何查看执行计划」(oracle执行计划怎么看)
- Oracle触发器执行:快速、完美实现业务处理(oracle 触发器执行)
- 新建Oracle数据库时关闭审计功能(oracle关闭审计功能)
- C语言操作Oracle数据库的游标实现(c 执行oracle游标)
- C语言实现Oracle函数调用的研究与实现(c 执行oracle函数)
- 进程Oracle揭秘睡眠进程的奥秘(oracle中睡眠)
- 分析Oracle作业执行日志,提升系统优化水平(oracle作业执行日志)
- 在Oracle中执行文件的技巧(oracle中执行文件)
- Oracle数据库中新增获取排序号的方法(oracle中获取排序号)
- 的运行轨迹Oracle永不停步的奔跑之路(oracle 一直执行中)
- Oracle任务执行记录跟踪可靠性(oracle job记录)