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字段:
SYS@br//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:
SYS@br//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字段:
SYS@br//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。
oracle 理解执行计划的更多相关文章
- 怎样看懂Oracle的执行计划
怎样看懂Oracle的执行计划 一.什么是执行计划 An explain plan is a representation of the access path that is taken when ...
- 【ORACLE】记录通过执行Oracle的执行计划查询SQL脚本中的效率问题
记录通过执行Oracle的执行计划查询SQL脚本中的效率问题 问题现象: STARiBOSS5.8.1R2版本中,河北对帐JOB执行时,无法生成发票对帐文件. 首先,Quartz表达式培植的启 ...
- (转)Oracle定时执行计划任务
Oracle定时执行计划任务 在日常工作中,往往有些事情是需要经常重复地做的,例如每天更新业务报表.每天从数据库中提取符合条件的数据.每天将客户关系管理系统中的数据分配给员工做数据库营销……因此我们就 ...
- Oracle的执行计划(来自百度文库)
如何开启oracle执行计划 http://wenku.baidu.com/view/7d1ff6bc960590c69ec37636.html怎样看懂Oracle的执行计划 http://wenku ...
- Oracle sql执行计划解析
Oracle sql执行计划解析 https://blog.csdn.net/xybelieve1990/article/details/50562963 Oracle优化器 Oracle的优化器共有 ...
- oracle sql 执行计划分析
转自http://itindex.net/detail/45962-oracle-sql-%E8%AE%A1%E5%88%92 一.首先创建表 SQL> show user USER is &q ...
- 分析 Oracle SQL 执行计划的关注点
本文内容摘自<剑破冰山--Oracle开发艺术>一书. 1.判定主要矛盾 在遇到复杂 SQL 语句时,执行计划也非常复杂,往往让人分析起来觉得无从下手,此时应避免顺序解决问题,而是快速定位 ...
- 分析oracle的执行计划(explain plan)并对对sql进行优化实践
基于oracle的应用系统很多性能问题,是由应用系统sql性能低劣引起的,所以,sql的性能优化很重要,分析与优化sql的性能我们一般通过查看该sql的执行计划,本文就如何看懂执行计划,以及如何通过分 ...
- Oracle 11g 执行计划管理2
1.创建测试数据 SQL> conn NC50/NC50 Connected. SQL)); SQL> insert into tab1 select rownum,object_name ...
随机推荐
- file_get_contents failed to open stream: HTTP request failed(一个字符决定成败)
file_get_contents 开始成功了.后来不知怎么的就报错,调试半天没发现什么问题. 结果.里面多了一个"空格"就报错.去掉空格就好了,你们仔细找找吧.
- eclipse一些操作记录
1.eclipse debug的时候想知道一个表达式执行的结果值,可以选中,按ctrl+shift+i来看返回的结果值: 2.eclipse java build path有个source,将so ...
- Response、Request、QueryString,修改,Cookies
Response对象:响应请求Response.Write("<script>alert('添加成功!')</script>");Response.Redi ...
- request-2高级用法
会话对象 会话对象让你能够跨请求保持某些参数.它也会在同一个session示例发出的所有请求之间保持cookie cookie与session的区别 1.cookie数据存放在客户的浏览器上,sess ...
- Appium录制脚本520-2
1.录制自动化脚本 场景:启动雪球,点击我的,登陆雪球,选择手机及其他登陆,输入手机号 2.使用Java进行测试Appium测试 2.1创建Java工程 file-创建maven工程-填写GroupI ...
- Linux 命令集合-错误
错误1 说明:在linux下,./xxx.sh执行shell脚本时会提示No such file or directory.但shell明明存在,为什么就是会提示这个呢? 这种其实是因为编码方式不对, ...
- width:100%和width:auto区别
在div父元素是body时 1.先看没有width限制的div <div style="border:1px solid red; margin-left:50px; margin-r ...
- ffmpeg 编码(视屏)
分析ffmpeg_3.3.2 muxing 1:分析主函数,代码如下: int main(int argc, char **argv) { OutputStream video_st = { }, a ...
- PHP mysqli_autocommit() 函数
定义和用法 mysqli_autocommit() 函数开启或关闭自动提交数据库修改. 提示:请查看 mysqli_commit() 函数,用于提交指定数据库连接的当前事务.请查看 mysqli_ro ...
- python 之路之函数01
一 函数 1 那么要想学习函数,我们首先应该知道函数是什么? 我们这里所说的函数与数学中的函数是不同的概念,在这里我们可以把函数看成我们写代码过程中需要用到的工具. 2 那么这个‘工具’有什么 ...