当前位置: 首页 > news >正文

oracle sql 执行计划分析_oracle sql 执行计划分析

oracle sql 执行计划分析

今天是2013-10-08,时间过的非常快,十月一就这样过去了,回想一下我感觉还是蛮不错的,1号与Amy相约青岛,两个人痛快的玩了两天,我们拍了很多照片,也感受到了彼此的快乐。四号到家开始在家干农活,在昨天的晚上我和我爸妈一直忙到晚上11点才把所有的棒子都剥完了。而现在的我已经正式来到“地狱”,开始我新的奋斗历程。

按照SunnyXu的笔记学习一下oracle的sql执行计划分析。

一、首先创建表

SQL> show user

USER is "RHYS"

SQL> create table A(col1 number(4,0),col2 number(4,0), col4 char(30));

create table B(col1 number(4,0),col3 number(4,0), name_b char(30));

create table C(col2 number(4,0),col3 number(4,0), name_c char(30));

Table created.

SQL>

Table created.

SQL>

Table created.

第二、查看一下执行计划。

1、

SQL> select a.col4 from c,a,b

2 where c.col3=5 and a.col1=b.col1 and a.col2=c.col2 and b.col3=10;

Execution Plan

----------------------------------------------------------

Plan hash value: 1485247927

------------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

------------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 1 | 110 | 6 (0)| 00:00:01 |

|* 1 | HASH JOIN | | 1 | 110 | 6 (0)| 00:00:01 |

| 2 | MERGE JOIN CARTESIAN| | 1 | 52 | 4 (0)| 00:00:01 |

|* 3 | TABLE ACCESS FULL | C | 1 | 26 | 2 (0)| 00:00:01 |

| 4 | BUFFER SORT | | 1 | 26 | 2 (0)| 00:00:01 |

|* 5 | TABLE ACCESS FULL | B | 1 | 26 | 2 (0)| 00:00:01 |

| 6 | TABLE ACCESS FULL | A | 1 | 58 | 2 (0)| 00:00:01 |

------------------------------------------------------------------------------

Predicate Information (identified by operation id):

---------------------------------------------------

1 - access("A"."COL1"="B"."COL1" AND "A"."COL2"="C"."COL2")

3 - filter("C"."COL3"=5)

5 - filter("B"."COL3"=10)

Note

-----

- dynamic sampling used for this statement (level=2)

执行计划主要查看:访问路径,连接顺序,连接方法

执行计划顺序为上内原则,同层次上边先执行,内层先执行。

plan hash value:当sql第一次在shared pool中进行执行的是硬解析并生产该hash值

id,只是一个标号,并不是实际执行顺序

operation:从字面意思也看出来就是操作的类型

name:对象的名字

rows:oracle估计该操作返回的行数

bytes:产生的数据量

cost:表示该sql执行 到此步骤的时候sql执行代价。

该sql的执行步骤如下:

首先执行id 3-》id5-》id4—》id2-》id6-》id1-》id0

首先对id3进行全表扫描过滤条件为filter("C"."COL3"=5),然后对表b进行全表扫描,条件为filter("B"."COL3"=10),完了之后再进行buffer sort排序,最后把3和4的row source 进行merge join 笛卡尔积操作,并把所有的结果作为row source1 ,也就是驱动表,然后把表A作为被探测表,两者进行hash join。这就是这一个过程信息。

注意此处在id5和id3没有关联的条件,就采用了笛卡尔积,这是不好的现象。

2、

SQL> select /*+ordered*/ a.col4 from c,a,b

2 where c.col3=5 and a.col1=b.col1 and a.col2=c.col2 and b.col3=10;

Execution Plan

----------------------------------------------------------

Plan hash value: 531790806

----------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

----------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 1 | 110 | 6 (0)| 00:00:01 |

|* 1 | HASH JOIN | | 1 | 110 | 6 (0)| 00:00:01 |

|* 2 | HASH JOIN | | 1 | 84 | 4 (0)| 00:00:01 |

|* 3 | TABLE ACCESS FULL| C | 1 | 26 | 2 (0)| 00:00:01 |

| 4 | TABLE ACCESS FULL| A | 1 | 58 | 2 (0)| 00:00:01 |

|* 5 | TABLE ACCESS FULL | B | 1 | 26 | 2 (0)| 00:00:01 |

----------------------------------------------------------------------------

Predicate Information (identified by operation id):

---------------------------------------------------

1 - access("A"."COL1"="B"."COL1")

2 - access("A"."COL2"="C"."COL2")

3 - filter("C"."COL3"=5)

5 - filter("B"."COL3"=10)

Note

-----

- dynamic sampling used for this statement (level=2)

使用hints可以调整optimizer的执行连接方法,在此例中我们指定了ordered使得采用hash join选取from 之后从左到有第一个表c作为驱动表。

执行顺序为:id3全表扫描过滤条件为filter("C"."COL3"=5)-》id4 全表扫描,然后表c为驱动表,a为探测表以此来进行hashjoin-》id5 全表扫描过滤条件为filter("B"."COL3"=10),此后执行id2为外部表,id5为被探测表进行hash join,从access访问路径可以看出首先是id2为("A"."COL2"="C"."COL2")此后为id1access("A"."COL1"="B"."COL1")。

这是整个sql执行的整个过程。

为了便于理解分析一下数据,

首先我要取到在表c中col3=5的所有数据,然后再内存进行hash,作为hash table,然后我在去使用该hash table去探测A表进行匹配,取出的数据为access("A"."COL2"="C"."COL2"),把最后的匹配结果作为row source,再次建立hash table表,然后再去探测b表,方式为:access("A"."COL1"="B"."COL1")。最终获得了0执行的结果信息。

对于note动态采样信息请参考:

http://www.oracle.com/technetwork/issue-archive/2009/09-jan/o19asktom-086775.html

由于本次没有对表进行analyze所有存有动态取样。

SQL> select /*+ordered use_nl(a c)*/ a.col4 from c,a,b

2 where c.col3=5 and a.col1=b.col1 and a.col2=c.col2 and b.col3=10;

Execution Plan

----------------------------------------------------------

Plan hash value: 1446226736

----------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

----------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 1 | 110 | 6 (0)| 00:00:01 |

|* 1 | HASH JOIN | | 1 | 110 | 6 (0)| 00:00:01 |

| 2 | NESTED LOOPS | | 1 | 84 | 4 (0)| 00:00:01 |

|* 3 | TABLE ACCESS FULL| C | 1 | 26 | 2 (0)| 00:00:01 |

|* 4 | TABLE ACCESS FULL| A | 1 | 58 | 2 (0)| 00:00:01 |

|* 5 | TABLE ACCESS FULL | B | 1 | 26 | 2 (0)| 00:00:01 |

----------------------------------------------------------------------------

Predicate Information (identified by operation id):

---------------------------------------------------

1 - access("A"."COL1"="B"."COL1")

3 - filter("C"."COL3"=5)

4 - filter("A"."COL2"="C"."COL2")

5 - filter("B"."COL3"=10)

Note

-----

- dynamic sampling used for this statement (level=2)

在这个语句中,表c和a进行了nested loops然后把结果惊醒hash table在与表b做jash join。

另外对于表有索引的情况进行如下分析。

首先创建表a的组合索引,索引列为(col1,col2)

eg:

SQL> create index inx_col12A on a(col1,col2);

Index created.

SQL> select A.col4

2 from C , A , B

3 where C.col3 = 5 and A.col1 = B.col1 and A.col2 = C.col2

4 and B.col3 = 10;

Execution Plan

----------------------------------------------------------

Plan hash value: 2122808611

-------------------------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

-------------------------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 1 | 110 | 4 (0)| 00:00:01 |

| 1 | NESTED LOOPS | | 1 | 110 | 4 (0)| 00:00:01 |

| 2 | NESTED LOOPS | | 1 | 110 | 4 (0)| 00:00:01 |

| 3 | MERGE JOIN CARTESIAN | | 1 | 52 | 4 (0)| 00:00:01 |

|* 4 | TABLE ACCESS FULL | C | 1 | 26 | 2 (0)| 00:00:01 |

| 5 | BUFFER SORT | | 1 | 26 | 2 (0)| 00:00:01 |

|* 6 | TABLE ACCESS FULL | B | 1 | 26 | 2 (0)| 00:00:01 |

|* 7 | INDEX RANGE SCAN | INX_COL12A | 1 | | 0 (0)| 00:00:01 |

| 8 | TABLE ACCESS BY INDEX ROWID| A | 1 | 58 | 0 (0)| 00:00:01 |

-------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):

---------------------------------------------------

4 - filter("C"."COL3"=5)

6 - filter("B"."COL3"=10)

7 - access("A"."COL1"="B"."COL1" AND "A"."COL2"="C"."COL2")

Note

-----

- dynamic sampling used for this statement (level=2)

这个比较有意思了。首先看一下执行顺序,首先对表c进行全表扫描过滤条件为col3=5取出数据作为row source1,然后再对b进行全表扫描过滤条件为col3=10,因为走的是merge join 笛卡尔积的排序连接,然后再buffer 进行sort作为row sources2 ,完了之后row source1和row source2作合并连接,完了之后作为row source1 是驱动表,然后再进行index range scan(索引范围扫描)访问路径为: access("A"."COL1"="B"."COL1" AND "A"."COL2"="C"."COL2"),完了之后把结果作为row source1 然后再去与表A进行嵌套循环操作,不过A也就是id8 走的是index rowid。完了之后再进行0获得数据。太繁琐了。呵呵。

SQL> select /*+ ORDERED USE_NL (A C)*/ A.col4

2 from C , A , B

3 where C.col3 = 5 and A.col1 = B.col1 and A.col2 = C.col2

4 and B.col3 = 10;

Execution Plan

----------------------------------------------------------

Plan hash value: 1446226736

----------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

----------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 1 | 110 | 6 (0)| 00:00:01 |

|* 1 | HASH JOIN | | 1 | 110 | 6 (0)| 00:00:01 |

| 2 | NESTED LOOPS | | 1 | 84 | 4 (0)| 00:00:01 |

|* 3 | TABLE ACCESS FULL| C | 1 | 26 | 2 (0)| 00:00:01 |

|* 4 | TABLE ACCESS FULL| A | 1 | 58 | 2 (0)| 00:00:01 |

|* 5 | TABLE ACCESS FULL | B | 1 | 26 | 2 (0)| 00:00:01 |

----------------------------------------------------------------------------

Predicate Information (identified by operation id):

---------------------------------------------------

1 - access("A"."COL1"="B"."COL1")

3 - filter("C"."COL3"=5)

4 - filter("A"."COL2"="C"."COL2")

5 - filter("B"."COL3"=10)

Note

-----

- dynamic sampling used for this statement (level=2)

当改变optimizer选择的执行计划时候,添加了hints,然后我们使用嵌套循环,驱动表为c,被驱动表为A,完了之后再作为row source1做为hash table, 然后与表B进行hash join。

SQL> select /*+ USE_NL (A C)*/ A.col4

2 from C , A , B

3 where C.col3 = 5 and A.col1 = B.col1 and A.col2 = C.col2

4 and B.col3 = 10;

Execution Plan

----------------------------------------------------------

Plan hash value: 2122808611

-------------------------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

-------------------------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 1 | 110 | 4 (0)| 00:00:01 |

| 1 | NESTED LOOPS | | 1 | 110 | 4 (0)| 00:00:01 |

| 2 | NESTED LOOPS | | 1 | 110 | 4 (0)| 00:00:01 |

| 3 | MERGE JOIN CARTESIAN | | 1 | 52 | 4 (0)| 00:00:01 |

|* 4 | TABLE ACCESS FULL | C | 1 | 26 | 2 (0)| 00:00:01 |

| 5 | BUFFER SORT | | 1 | 26 | 2 (0)| 00:00:01 |

|* 6 | TABLE ACCESS FULL | B | 1 | 26 | 2 (0)| 00:00:01 |

|* 7 | INDEX RANGE SCAN | INX_COL12A | 1 | | 0 (0)| 00:00:01 |

| 8 | TABLE ACCESS BY INDEX ROWID| A | 1 | 58 | 0 (0)| 00:00:01 |

-------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):

---------------------------------------------------

4 - filter("C"."COL3"=5)

6 - filter("B"."COL3"=10)

7 - access("A"."COL1"="B"."COL1" AND "A"."COL2"="C"."COL2")

Note

-----

- dynamic sampling used for this statement (level=2)

SQL>

SQL> set autotrace off

SQL> analyze table a compute statistics;

Table analyzed.

SQL> analyze table b compute statistics;

Table analyzed.

SQL> analyze table c compute statistics;

Table analyzed.

SQL> analyze index inx_col12A compute statistics;

Index analyzed.

SQL> select A.col4

2 from C , A , B

3 where C.col3 = 5 and A.col1 = B.col1 and A.col2 = C.col2

4 and B.col3 = 10;

no rows selected

SQL> set auotrace trace explain

SP2-0158: unknown SET option "auotrace"

SQL> set autotrace trace explain

SQL> r

1 select A.col4

2 from C , A , B

3 where C.col3 = 5 and A.col1 = B.col1 and A.col2 = C.col2

4* and B.col3 = 10

Execution Plan

----------------------------------------------------------

Plan hash value: 2122808611

-------------------------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

-------------------------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 1 | 110 | 4 (0)| 00:00:01 |

| 1 | NESTED LOOPS | | 1 | 110 | 4 (0)| 00:00:01 |

| 2 | NESTED LOOPS | | 1 | 110 | 4 (0)| 00:00:01 |

| 3 | MERGE JOIN CARTESIAN | | 1 | 52 | 4 (0)| 00:00:01 |

|* 4 | TABLE ACCESS FULL | C | 1 | 26 | 2 (0)| 00:00:01 |

| 5 | BUFFER SORT | | 1 | 26 | 2 (0)| 00:00:01 |

|* 6 | TABLE ACCESS FULL | B | 1 | 26 | 2 (0)| 00:00:01 |

|* 7 | INDEX RANGE SCAN | INX_COL12A | 1 | | 0 (0)| 00:00:01 |

| 8 | TABLE ACCESS BY INDEX ROWID| A | 1 | 58 | 0 (0)| 00:00:01 |

-------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):

---------------------------------------------------

4 - filter("C"."COL3"=5)

6 - filter("B"."COL3"=10)

7 - access("A"."COL1"="B"."COL1" AND "A"."COL2"="C"."COL2")

相关文章:

  • python读取网络摄像头_python 处理网络摄像头
  • vertx源码_使用Vertx构建微服务-阿里云开发者社区
  • 固有属性指的是用户_用户画像-带你认清的你的用户
  • ai如何对齐两个图形边缘_UI设计中如何更好的运用排版法则
  • 世界地图新西兰_新西兰又被实名羡慕了!在这个榜单排名第1,美国才排第34!...
  • 字体感觉小了 引入的vant_Vant中使用rem
  • eplices开发android_Eclipse 安装(Neon 版本)
  • 加密狗模拟器_汽车驾驶模拟器新软件功能
  • 触摸屏开发_莱宝高科:暂无大规模扩充触摸屏产能计划,正开发OFM结构触摸屏...
  • 模拟黑洞图像_nasa绘制黑洞图像(这次我终于看到了! NASA模拟的黑洞高清令人震惊的画面,令人窒息!)...
  • github覆盖远程分支内容_Github快速上手笔记
  • 显示某年某月日历_一眼就沦陷!一款深藏中国文化古韵的日历应用
  • 深度装机大师一键重装_深度一键重装系统软件
  • idea jsp引用路径_JSP学习4
  • 于朦胧 机器人_《两世欢》上线,于朦胧演技成笑点:像个没有感情的走路机器人...
  • 【JavaScript】通过闭包创建具有私有属性的实例对象
  • 【划重点】MySQL技术内幕:InnoDB存储引擎
  • Bytom交易说明(账户管理模式)
  • Java 多线程编程之:notify 和 wait 用法
  • JAVA并发编程--1.基础概念
  • Java知识点总结(JavaIO-打印流)
  • js学习笔记
  • Python3爬取英雄联盟英雄皮肤大图
  • Vue 重置组件到初始状态
  • vue-cli在webpack的配置文件探究
  • 初识 beanstalkd
  • 大整数乘法-表格法
  • 如何在 Intellij IDEA 更高效地将应用部署到容器服务 Kubernetes ...
  • 数据库巡检项
  • 说说我为什么看好Spring Cloud Alibaba
  • 微龛半导体获数千万Pre-A轮融资,投资方为国中创投 ...
  • 昨天1024程序员节,我故意写了个死循环~
  • (WSI分类)WSI分类文献小综述 2024
  • (附源码)python房屋租赁管理系统 毕业设计 745613
  • (附源码)spring boot北京冬奥会志愿者报名系统 毕业设计 150947
  • (每日持续更新)jdk api之FileReader基础、应用、实战
  • (四)汇编语言——简单程序
  • (一)基于IDEA的JAVA基础10
  • (幽默漫画)有个程序员老公,是怎样的体验?
  • (转)清华学霸演讲稿:永远不要说你已经尽力了
  • **PyTorch月学习计划 - 第一周;第6-7天: 自动梯度(Autograd)**
  • .aanva
  • .CSS-hover 的解释
  • .NET CORE Aws S3 使用
  • .net core webapi 部署iis_一键部署VS插件:让.NET开发者更幸福
  • .NET Core 中的路径问题
  • .NET/C# 中设置当发生某个特定异常时进入断点(不借助 Visual Studio 的纯代码实现)
  • .NET6 开发一个检查某些状态持续多长时间的类
  • /usr/bin/python: can't decompress data; zlib not available 的异常处理
  • :“Failed to access IIS metabase”解决方法
  • [ vulhub漏洞复现篇 ] AppWeb认证绕过漏洞(CVE-2018-8715)
  • [ vulhub漏洞复现篇 ] Jetty WEB-INF 文件读取复现CVE-2021-34429
  • [ 英语 ] 马斯克抱水槽“入主”推特总部中那句 Let that sink in 到底是什么梗?
  • [AutoSar]工程中的cpuload陷阱(三)测试
  • [C]编译和预处理详解