当前位置: 代码网 > it编程>数据库>MsSqlserver > Oracle查看SQL执行计划的几种方法

Oracle查看SQL执行计划的几种方法

2024年11月13日 MsSqlserver 我要评论
oracle查看sql执行计划的方法一.使用autotrace查看执行计划我们利用sqlplus中自带的autotrace工具查看执行计划。autotrace用法如下。set autot on:该命令

oracle查看sql执行计划的方法

一.使用autotrace查看执行计划

我们利用sqlplus中自带的autotrace工具查看执行计划。autotrace用法如下。

set autot on:			该命令会运行sql并且显示运行结果,执行计划和统计信息。
set autot trace:		该命令会运行sql,但不显示运行结果,会显示执行计划和统计信息。
set autot trace exp:	运行该命令查询语句不执行,dml语句会执行,只显示执行计划。
set autot trace stat:	该命令会运行 sql,只显示统计信息。
set autot off:			关闭 autotrace。

-执行计划中的各个参数解释
recursive calls 			表示递归调用的次数,一个sql第一次执行就会发生硬解析,在硬解析的时候,优化器会隐含地调用一些内部sql,因此当一个sql第一次执行,recursive calls会大于0,第二次执行的时候不需要递归调用,recursive calls就会等于0,如果sql语句中有自定义函数,recursive calls永远不会等于0,自定义函数被调用了多少次,recursive calls就会显示为多少次
db block gets				表示有多少块发生变化,一般情况下只有dml语句才会导致块发生变化,所以查询语句中的db block gets一般为0
consistent gets				表示逻辑读,单位是块。在sql优化的时候我们应该想方设法减少逻辑读的个数,通常情况下逻辑读越小,性能越好。需要注意的是,逻辑读并不是衡量sql执行快慢的唯一标准,需要结合i/o
physical reads				表示从磁盘读取了多少个数据块,也就是物理读。如果表已经被缓存在buffer cache中,没有物理读,那么会等于0
redo size					表示产生了多少字节的重做日志,一般也是只有dml语句会产生redo,查询语句一般情况下不会产生redo
bytes sent via sql*net to client					表示从数据库服务器发送了多少字节到客户端
bytes received via sql*net from client				表示从客户端发送了多少字节到服务端
sql*net roundtrips to/from client					表示客户端与数据库服务端交互次数,我们可以通过设置arraysize减少交互次数
sorts (memory)				内存排序的次数
sorts (disk)				磁盘排序的次数
rows processed				表示sql一共返回多少行数据。我们在做sql优化的时候最关心这部分数据,因为可以根据sql返回的行数判断整个sql应该是走hash连接还是走嵌套循环。如果rows processed很大,一般走hash连接,如果rows processed很小,一般走嵌套循环。

二.使用explain plan for查看执行计划

用法如下

explain plan for sql语句;
select * from table(dbms_xplan.display);

-查看高级(advanced)执行计划:
explain plan for sql语句;
select * from table(dbms_xplan.display(null, null,'advanced -projection'));

三.查看带有a-time的执行计划

alter session set statistics_level = all;
select count(*) from test;
select * from table(dbms_xplan.display_cursor(null, null,'allstats last'));

或者在sql语句中添加hint:/*+ gather_plan_statistics */
select /*+ gather_plan_statistics */ count(*) from test where owner='sys';
select * from table(dbms_xplan.display_cursor(null, null,'allstats last'));

starts			表示这个操作执行的次数。
e-rows			表示优化器估算的行数,就是普通执行计划中的rows。
a-rows			表示真实的行数。
a-time			表示累加的总时间。与普通执行计划不同的是,普通执行计划中的time是假的,而a-time是真实的。
buffers			表示累加的逻辑读。
reads			表示累加的物理读。

上面介绍了3种方法查看执行计划。
使用autotrace或者explain plan for获取的执行计划来自于plan_table。
plan_table是一个会话级的临时表,里面的执行计划并不是sql真实的执行计划,它只是优化器估算出来的。
真实的执行计划不应该是估算的,应该是真正执行过的。sql执行过的执行计划存在于共享池中,具体存在于数据字典v$sql_plan中。
带有a-time的执行计划来自于v$sql_plan,是真实的执行计划,而通过autotrace、通过explain plan for获取的执行计划只是优化器估算获得的执行计划。

四.查看正在执行的sql的执行计划

有时需要抓取正在运行的sql的执行计划,这时我们需要获取sql的sql_id以及sq的child_numebr,然后将其代入下面sql,就能获取正在运行的sql的执行计划。

select * from table(dbms_xplan.display_cursor('sql_id',child_number));

-在一个会话中执行如下sql。
select count(*) from a,b where a.owner=b.owner;

-在另外一个会话中执行如下sql  找出sql的sql_id和child_number
select a.sid, a.event, a.sql_id, a.sql_child_number, b.sql_text
  from v$session a, v$sql b
 where a.sql_address = b.address
   and a.sql_hash_value = b.hash_value
   and a.sql_child_number = b.child_number
 order by 1 desc;
 
-接下来我们将 sql_id 和 child_number 代入以下sql。
select * from table(dbms_xplan.display_cursor('czr9jwxv0xra6',0));

到此这篇关于oracle查看sql执行计划的几种方法的文章就介绍到这了,更多相关oracle查看sql执行计划内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com