·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. JZ2440 裸机驱动 第7章 内存管理单元MMU

    本章目标:     了解虚拟地址和物理地址的关系:     掌握如何通过设置MMU来控制虚拟地址到物理地址的转化:     了解MMU的内存访问权限机制:     了解TLB.Cache.Write ...

  2. 【python】globle的使用

    python中直接定义的变量就是本地变量,使用global定义的变量就是全局变量.比如: a = 1 b = 1 def foo1(): global b #申明使用全局b a = 2 #a是本地变量 ...

  3. bzoj2263: Pku3889 Fractal Streets

    给出两点编号,求如图所示的图中两点间欧氏距离*10取整 递归处理由编号求出坐标 #include<cstdio> #include<cmath> int T,n,s,t; vo ...

  4. 垃圾收集器之:CMS收集器

    HotSpot JVM的并发标记清理收集器(CMS收集器)的主要目标就是:低应用停顿时间.该目标对于大多数交互式应用很重要,比如web应用.在我们看一下有关JVM的参数之前,让我们简要回顾CMS收集器 ...

  5. python 可视化 散点图。柱状图、等高线

    matplolib.org可查到更多画图方法等 散点图 import matplotlib.pyplot as plt import numpy as np #n个点 n = 1024 #平均值是0, ...

  6. 杂项-性能测试工具:LoadRunner

    ylbtech-杂项-性能测试工具:LoadRunner LoadRunner,是一种预测系统行为和性能的负载测试工具.通过以模拟上千万用户实施并发负载及实时性能监测的方式来确认和查找问题,LoadR ...

  7. python selenium-2 定位元素

    元素 方法 示例 id find_element_by_id('su') driver.get("http://www.baidu.com")driver.find_element ...

  8. redis sentinel无法启动问题

    redis sentinel 正常启动 ./redis-sentinel sentinel.conf 就可以启动, 但是如果linux 操作系统(比如阿里云os)不支持ipv6,就会导致sentine ...

  9. dbms_xplan之display_cursor函数的使用

    DBMS_XPLAN包中display_cursor函数不同于display函数,display_cursor用于显示SQL语句的真实的执行计划,在大多数情况下,显示真实的执行计划有助于更好的分析SQ ...

  10. oracle 收集的一些图

    ================================================ ================================================ da ...