Oracle数据库SQL执行计划怎么查看?如何分析?

数据库 潘老师 2年前 (2021-11-19) 6142 ℃ (1) 扫码查看

数据库SQL执行的效率会直接影响整体应用的性能,在大数据量和复杂SQL语句的情况下,一定要查看数据库SQL的执行计划,并分析哪些语句耗费较多,值得优化!就Oracle数据库而言,下面潘老师来谈谈我们该如何去查询和分析执行计划?

一、什么是SQL执行计划

执行计划(explain plan)是指:一条查询语句在数据库中的执行过程或访问路径的描述。

二、Oracle数据库如何查看SQL执行计划

1)PLSQL工具查看方式
Oracle数据库查看SQL执行计划可以通过客户端工具快速实现,比如使用plsql直接快捷键F5或者点击菜单:工具->解释计划都可以查看对应的SQL的执行计划,效果类似如下:
Oracle数据库SQL执行计划怎么查看?如何分析?
另外PLSQL的默认显示首选项参数比较少,可以点击图中的首选项来配置:
Oracle数据库SQL执行计划怎么查看?如何分析?
2)Navicat For Oracle查看方式
Navicat 可以直接点击右上角的Explain就可以查看
Oracle数据库SQL执行计划怎么查看?如何分析?
3)SQL-PLUS可以使用如下sql语句进行查看

# 解释计划
EXPLAIN PLAN FOR ELECT * FROM TEST_TABLE; --要解析的SQL脚本
# 查看解释计划
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);

三、SQL执行计划常用概念解释

1、说明一下部分相关概念
相比较而言还是plsql较为好用,以plsql为例。
1)基数(Rows):Oracle估计的当前操作的返回结果集行数
2)字节(Bytes):执行该步骤后返回的字节数
3)耗费(Cost)、CPU耗费:Oracle估计的该步骤的执行成本,用于说明SQL执行的代价,理论上越小越好(该值可能与实际有出入)
4)时间(Time):Oracle估计的当前操作所需的时间
5)访问谓词:where后面的查询条件

2、执行顺序
在plsql中我们可以使用图中的箭头直接来调试执行顺序,非常方便,像Navicat没有就可以根据据Operation缩进来判断,缩进最多的最先执行(当缩进相同时,最上面的最先执行),同一级如果某个动作没有子ID就最先执行,同一级的动作执行时遵循最上最右先执行的原则。

3、一些动作的解释
如plsql那张图中类似INDEX RANGE SCANTABLE ACCESS FULL等等,即描述的是该动作执行时表访问(或者说Oracle访问数据)的方式;

常见的几种表访问方式:

TABLE ACCESS FULL:全表扫描
TABLE ACCESS BY ROWID:通过ROWID的表存取
TABLE ACCESS BY INDEX SCAN:索引扫描

1)全表扫描:
Oracle会读取表中所有的行,并检查每一行是否满足SQL语句中的 Where 限制条件;全表扫描时可以使用多块读(即一次I/O读取多块数据块)操作,提升吞吐量;
使用建议:数据量太大的表不建议使用全表扫描,除非本身需要取出的数据较多,占到表数据总量的 5% ~ 10% 或以上。

2)通过ROWID的表存取
ROWID是由Oracle自动加在表中每行最后的一列伪列,既然是伪列,就说明表中并不会物理存储ROWID的值,你可以像使用其它列一样使用它,只是不能对该列的值进行增、删、改操作,一旦一行数据插入后,则其对应的ROWID在该行的生命周期内是唯一的,即使发生行迁移,该行的ROWID值也不变。

让我们再回到 TABLE ACCESS BY ROWID 来:行的ROWID指出了该行所在的数据文件、数据块以及行在该块中的位置,所以通过ROWID可以快速定位到目标数据上,这也是Oracle中存取单行数据最快的方法;

3)索引扫描
在索引块中,既存储每个索引的键值,也存储具有该键值的行的ROWID。扫描其实分为两步:
Ⅰ:扫描索引得到对应的ROWID
Ⅱ:通过ROWID定位到具体的行读取数据

索引扫描又分五种:

INDEX UNIQUE SCAN:索引唯一扫描
INDEX RANGE SCAN:索引范围扫描
INDEX FULL SCAN:索引全扫描
INDEX FAST FULL SCAN:索引快速扫描
INDEX SKIP SCAN:索引跳跃扫描

a) INDEX UNIQUE SCAN(索引唯一扫描):

针对唯一性索引(UNIQUE INDEX)的扫描,每次至多只返回一条记录;表中某字段存在 UNIQUE、PRIMARY KEY 约束时,Oracle常实现唯一性扫描;

b) INDEX RANGE SCAN(索引范围扫描):

使用一个索引存取多行数据;发生索引范围扫描的三种情况:

    在唯一索引列上使用了范围操作符(如:> < <> >= <= between) 在组合索引上,只使用部分列进行查询(查询时必须包含前导列,否则会走全表扫描) 对非唯一索引列上进行的任何查询[/list] c) INDEX FULL SCAN(索引全扫描):
    进行全索引扫描时,查询出的数据都必须从索引中可以直接得到(注意全索引扫描只有在CBO模式下才有效)
    d) INDEX FAST FULL SCAN(索引快速扫描):
    扫描索引中的所有的数据块,与 INDEX FULL SCAN 类似,但是一个显著的区别是它不对查询出的数据进行排序(即数据不是以排序顺序被返回)
    e) INDEX SKIP SCAN(索引跳跃扫描):
    Oracle 9i后提供,有时候复合索引的前导列(索引包含的第一列)没有在查询语句中出现,oralce也会使用该复合索引,这时候就使用的INDEX SKIP SCAN;

    大概怎么用

    当然还有一些表连接方式的动态在此就不再展开了,我们在优化SQL时重要的一步就是尽量避免了全表扫描,查看SQL是否命中索引,优化COST较大的执行步骤!

    以上就是Oracle数据库SQL执行计划怎么查看分析的内容,至于具体怎么优化SQL以后再说。


    版权声明:本站文章,如无说明,均为本站原创,转载请注明文章来源。如有侵权,请联系博主删除。
    本文链接:https://www.panziye.com/java/database/3982.html
    喜欢 (8)
    请潘老师喝杯Coffee吧!】
    分享 (0)
    用户头像
    发表我的评论
    取消评论
    表情 贴图 签到 代码

    Hi,您需要填写昵称和邮箱!

    • 昵称【必填】
    • 邮箱【必填】
    • 网址【可选】

    (1) 个小伙伴在畅所欲言
    1. 用户头像
      写的很好,具体怎么优化 有吗
      少林退役武僧 2022-08-03 11:05 回复