·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. VS2010安装选项中有个“图标库”

    位置 :\Program Files\Microsoft Visual Studio 10.0\Common7\VS2010ImageLibrary\2052\VS2010ImageLibrary.z ...

  2. jni头文件自动生成

    写一个测试代码,大概如下 package aa.bb; public class TestClass { public native void aaaBBB(); } 在项目的src目录下执行 jav ...

  3. FPGA配置方式

    FPGA有多种配置/加载方式.粗略可以分为主动和被动两种.主动加载是指由FPGA控制配置流程,被动加载是指FPGA仅仅被动接收配置数据. 最常见的被动配置模式就是JTAG下载bit文件.此模式下,主动 ...

  4. java ssl https 连接详解 生成证书 tomcat keystone

    java ssl https 连接详解 生成证书 我们先来了解一下什么理HTTPS 1. HTTPS概念 1)简介 HTTPS(全称:Hypertext Transfer Protocol over ...

  5. 9-16Jenkins-3可用的环境变量、参数化构建和依赖

    1.环境变量 可以查看可用的环境量 执行构建 2.参数化构建 3.依赖 多个工程可以在按既定顺序执行 test1225-2的构建触发器设置

  6. RedisCluster读写分离改造

      RedisCluster模式启动的环境中,通过Redis中的每个连接,都可以访问 cluster nodes 访问到所有的服务器列表以及其所处于的角色(master/slave).对于RedisC ...

  7. javascript创建对象之动态原型模式(五)

    function Human(name, sex) { this.name = name; this.sex = sex; if (typeof this.say != "function& ...

  8. jQuery 的noConflict()的使用.

    我们项目现在需要用到两个js库.一个是jQuery库,还有一个是我们自己开发的轻量级的gys.js库. 而gys库对外提供的接口也是$符号.和jQuery库是一样的,这个时候,两个库就会发生冲突了,我 ...

  9. Vue 封装js

    //封装模块化文件 新建的.js文件 var storage = { set(key, value) { localStorage.setItem(key, JSON.stringify(value) ...

  10. Linux操作系统,服务器端的主流

    1.无意之间,一直使用的Windows,其实也是在Unix的基础之上开发的,什么xp,win7等都是,就是Unix的一些堆砌,其实这样说也不对.但是windows的复杂程度比Linux要复杂,因为Wi ...