·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 理解执行计划的更多相关文章

  1. 怎样看懂Oracle的执行计划

    怎样看懂Oracle的执行计划 一.什么是执行计划 An explain plan is a representation of the access path that is taken when ...

  2. 【ORACLE】记录通过执行Oracle的执行计划查询SQL脚本中的效率问题

    记录通过执行Oracle的执行计划查询SQL脚本中的效率问题   问题现象: STARiBOSS5.8.1R2版本中,河北对帐JOB执行时,无法生成发票对帐文件.   首先,Quartz表达式培植的启 ...

  3. (转)Oracle定时执行计划任务

    Oracle定时执行计划任务 在日常工作中,往往有些事情是需要经常重复地做的,例如每天更新业务报表.每天从数据库中提取符合条件的数据.每天将客户关系管理系统中的数据分配给员工做数据库营销……因此我们就 ...

  4. Oracle的执行计划(来自百度文库)

    如何开启oracle执行计划 http://wenku.baidu.com/view/7d1ff6bc960590c69ec37636.html怎样看懂Oracle的执行计划 http://wenku ...

  5. Oracle sql执行计划解析

    Oracle sql执行计划解析 https://blog.csdn.net/xybelieve1990/article/details/50562963 Oracle优化器 Oracle的优化器共有 ...

  6. oracle sql 执行计划分析

    转自http://itindex.net/detail/45962-oracle-sql-%E8%AE%A1%E5%88%92 一.首先创建表 SQL> show user USER is &q ...

  7. 分析 Oracle SQL 执行计划的关注点

    本文内容摘自<剑破冰山--Oracle开发艺术>一书. 1.判定主要矛盾 在遇到复杂 SQL 语句时,执行计划也非常复杂,往往让人分析起来觉得无从下手,此时应避免顺序解决问题,而是快速定位 ...

  8. 分析oracle的执行计划(explain plan)并对对sql进行优化实践

    基于oracle的应用系统很多性能问题,是由应用系统sql性能低劣引起的,所以,sql的性能优化很重要,分析与优化sql的性能我们一般通过查看该sql的执行计划,本文就如何看懂执行计划,以及如何通过分 ...

  9. Oracle 11g 执行计划管理2

    1.创建测试数据 SQL> conn NC50/NC50 Connected. SQL)); SQL> insert into tab1 select rownum,object_name ...

随机推荐

  1. 学习 ASP.NET MVC

    http://www.cnblogs.com/gaoweipeng/category/203080.html http://blog.csdn.net/liu_ben_qian/article/det ...

  2. BASIC-1_蓝桥杯_闰年判断

    正确代码: #include <stdio.h> int main(void){ int year = 0 ; scanf("%d",&year); if (y ...

  3. vs 2017/2015/2013 如何定位C++内存泄漏

    定位内存泄漏是C++的一个大问题 我们可以通过如下方式进行定位: //在主函数文件中加入如下代码 #include <stdlib.h> #include <crtdbg.h> ...

  4. windows下elasticsearch配置及spring boot 简单demod的 整合

    学习过程: elasticsearch 下载安装 elasticsearch-head 安装 spring boot 下elasticsearch的配置 使用ElasticsearchReposito ...

  5. httpclient 用户名密码认证实例

    import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.apache.com ...

  6. 接口测试3-3Excel格式

    java操作Excel,需要第三方库poi #xml <dependency> <groupId>org.apache.poi</groupId> <arti ...

  7. 动画js版本

    动画: 1)css样式提供运动 2)js提供的运动 过渡的属性:transition 从一种情况到另一种情况叫过渡 transition:变化的属性  (attr) transition:花费的时间  ...

  8. application/xml 和 text/xml的区别

    application/xml and text/xml的区别 经常看到有关xml时提到"application/xml" 和 "text/xml"两种类型, ...

  9. 运用map并于执行期指定排序准则

    该例展示以下技巧: 如何使用map 如何撰写和使用仿函数 如何在执行期定义排序规则 如何在"不在乎大小写"的情况下比较字符串 #include<iostream> #i ...

  10. sql isdate判断时间函数(小技巧)

    isdate 是一个判断字符串是否为日期的函数,0代表所传入的字符串不是日期,1代表传入的参数是日期. select   isdate('30/12/2014')  ---0 第一个是 mdy --如 ...