微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Oracle删除一条SQL在Shared Pool里缓存的执行计划的三种方法

在Oracle里第一次执行一条sql语句后,该sql语句会被硬解析,而且执行计划和解析树会被缓存到Shared Pool里。方便以后再次执行这条sql语句时不需要再做硬解析,方便应用系统的扩展。但是如果该sql对应的表数据量突变或其他原因,Shared Pool里缓存的执行计划和解析树已经不再适用于现在的情况,sql执行效率急速下降,这种情况下就需要把该sql缓存在Shared Pool里的执行计划和解析树清理出去,以便对该sql重新做硬解析,生成新的执行计划和解析树。

从Shared Pool删除sql缓存的执行计划有三种方法

  • alter system flush shared_pool;

  • 对表做DDL操作

  • dbms_shared_pool.purge包(10.2.0.4及其以上)

上面三种方法的影响范围依次递减,下面分别用实例做演示

创建测试表

zx@MYDB>createtables1asselect*fromdba_objects;

Tablecreated.

zx@MYDB>createtables2asselect*fromdba_objects;

Tablecreated.

1、alter system flush shared_pool;

这条命令是清除Shared Pool里缓存的所有数据,自然可以删除想要删除sql对就的执行计划,但负作用是它把Shared Pool里的所有数据都清除了,影响太大。生产系统一定要谨慎使用这个命令。

执行两个查询,并查看在Shared Pool里的缓存

zx@MYDB>selectobject_namefroms1whereobject_id=20;

OBJECT_NAME
------------------------------
ICOL$

zx@MYDB>selectobject_namefroms2whereobject_id=20;

OBJECT_NAME
------------------------------
ICOL$

zx@MYDB>colsql_textfora80
zx@MYDB>selectsql_text,sql_id,version_count,executionsfromv$sqlareawheresql_textlike'selectobject_namefroms%';

sql_TEXT									sql_ID				VERSION_COUNTEXECUTIONS
----------------------------------------------------------------------------------------------------------------------------------------------
selectobject_namefroms1whereobject_id=20					1s45nwjtws2tj					1		1
selectobject_namefroms2whereobject_id=20					a6gw4ht2unxun					1		1

zx@MYDB>selectobject_namefroms1whereobject_id=20;

OBJECT_NAME
------------------------------
ICOL$

zx@MYDB>selectsql_text,executionsfromv$sqlareawheresql_textlike'selectobject_namefroms%';

sql_TEXT									sql_ID				VERSION_COUNTEXECUTIONS
----------------------------------------------------------------------------------------------------------------------------------------------
selectobject_namefroms1whereobject_id=20					1s45nwjtws2tj					1		2
selectobject_namefroms2whereobject_id=20					a6gw4ht2unxun					1		1

上面查询分别对表s1和表s2做查询,从输出可以看出上面执行的两个sql的执行计划和解析树被缓存到了Shared Pool中,再次执行时会直接用缓存的执行计划(EXECUTIONS变为2)。现在想删除表s1对应sql的执行计划,执行alter system flush shared_pool;

zx@MYDB>altersystemflushshared_pool;

Systemaltered.

zx@MYDB>selectsql_text,executionsfromv$sqlareawheresql_textlike'selectobject_namefroms%';

norowsselected

从上面查询结果可以看出命令确实删除了s1对应sql的执行计划,但同时也把表s2对应的sql的执行计划也删除了,伤及了无辜。

2、对表做DDL操作

一旦对某个表执行了DDL操作,库缓存中所有在sql文本中包含了这个表的Shared Cursor都会被Oracle标记为失效(invalid),这意味着这些Shared Cursor中存储的解析树和执行计划将不再能被重用,所以当Oracle再次执行与这个表相关的sql时就会使用硬解析。但这种方法的弊端在于其影响范围还是太广,因为一旦对某个表执行了DDL操作,再次执行与这个表相关的所有sql时就会全部使用硬解析。这是很不好的,特别是对于OLTP类型的应用系统而言,因为这可能会导致短时间内的硬解析数量剧增,进而影响系统的性能

zx@MYDB>selectobject_namefroms1whereobject_id=20;

OBJECT_NAME
------------------------------
ICOL$

zx@MYDB>selectobject_namefroms1whereobject_id=30;

OBJECT_NAME
------------------------------
I_COBJ#

zx@MYDB>selectsql_text,executionsfromv$sqlareawheresql_textlike'selectobject_namefroms%';

sql_TEXT									sql_ID				VERSION_COUNTEXECUTIONS
----------------------------------------------------------------------------------------------------------------------------------------------
selectobject_namefroms1whereobject_id=20					1s45nwjtws2tj					1		1
selectobject_namefroms1whereobject_id=30					1hdyqyxhtavqs					1		1

zx@MYDB>selectobject_namefroms1whereobject_id=20;

OBJECT_NAME
------------------------------
ICOL$

zx@MYDB>selectsql_text,executionsfromv$sqlareawheresql_textlike'selectobject_namefroms%';

sql_TEXT									sql_ID				VERSION_COUNTEXECUTIONS
----------------------------------------------------------------------------------------------------------------------------------------------
selectobject_namefroms1whereobject_id=20					1s45nwjtws2tj					1		2
selectobject_namefroms1whereobject_id=30					1hdyqyxhtavqs					1		1

上面查询对表s1做了两个不同的查询,从输出可以看出上面执行的两个sql的执行计划和解析树被缓存到了Shared Pool中,再次执行时会直接用缓存的执行计划(EXECUTIONS变为2)。现在要删除object_id=20对应sql的执行计划,这里选择对表添加注释(COMMENT),它也是DDL操作。

zx@MYDB>commentontables1is'testsharedcursor';

Commentcreated.

zx@MYDB>selectsql_text,executions,OBJECT_STATUSfromv$sqlareawheresql_textlike'selectobject_namefroms%';

sql_TEXT									sql_ID				VERSION_COUNTEXECUTIONSOBJECT_STATUS
-------------------------------------------------------------------------------------------------------------------------------------------------------------
selectobject_namefroms1whereobject_id=20					1s45nwjtws2tj					1		2INVALID_UNAUTH
selectobject_namefroms1whereobject_id=30					1hdyqyxhtavqs					1		1INVALID_UNAUTH

zx@MYDB>selectobject_namefroms1whereobject_id=20;

OBJECT_NAME
------------------------------
ICOL$

zx@MYDB>selectsql_text,OBJECT_STATUSfromv$sqlareawheresql_textlike'selectobject_namefroms%';

sql_TEXT									sql_ID				VERSION_COUNTEXECUTIONSOBJECT_STATUS
-------------------------------------------------------------------------------------------------------------------------------------------------------------
selectobject_namefroms1whereobject_id=20					1s45nwjtws2tj					1		1VALID
selectobject_namefroms1whereobject_id=30					1hdyqyxhtavqs					1		1INVALID_UNAUTH

从上面的输出可以看出,对表s1做DDL操作后缓存在Shared Pool里的执行计划没有被清除,但是两个sql对应的执行计划状态都变为了“INVALID_UNAUTH”,当再次执行sql时会做硬解析,重新缓存解析树和执行计划。

3、dbms_shared_pool.purge包

它是从Oracle 10.2.0.4开始引入的一种方法,它可以用来删除指定的缓存在库缓存中的Shared Cursor,其影响范围公限于目标sql所对应的Shared Cursor,也就是说它可以做到让Oracle在执行目标sql时使用硬解析,在执行其他所有sql时都和原来一样保持不变。

zx@MYDB>altersystemflushshared_pool;

Systemaltered.

zx@MYDB>selectobject_namefroms1whereobject_id=20;

OBJECT_NAME
------------------------------
ICOL$

zx@MYDB>selectobject_namefroms1whereobject_id=30;

OBJECT_NAME
------------------------------
I_COBJ#

zx@MYDB>selectsql_text,OBJECT_STATUS,address,hash_valuefromv$sqlareawheresql_textlike'selectobject_namefroms%';

sql_TEXT						sql_ID				VERSION_COUNTEXECUTIONSOBJECT_STATUSADDRESS	HASH_VALUE
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
selectobject_namefroms1whereobject_id=20		1s45nwjtws2tj					1	1VALID	00000000B4F85A181942752049
selectobject_namefroms1whereobject_id=30		1hdyqyxhtavqs					1	1VALID	00000000BE7E56C81637183192

现在要删除object_id=20对应的sql缓存的执行计划和解析树。

zx@MYDB>execsys.dbms_shared_pool.purge('00000000B4F85A18,1942752049','C');

PL/sqlproceduresuccessfullycompleted.

zx@MYDB>selectsql_text,hash_valuefromv$sqlareawheresql_textlike'selectobject_namefroms%';

sql_TEXT						sql_ID				VERSION_COUNTEXECUTIONSOBJECT_STATUSADDRESS	HASH_VALUE
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
selectobject_namefroms1whereobject_id=30		1hdyqyxhtavqs					1	1VALID	00000000BE7E56C81637183192

输出可以看出object_id=20对应的sql缓存的执行计划和解析树被删除了,而object_id=30对应的sql的执行计划没有受影响。

需要注意的是,如果在10.2.0.4中使用dbms_shared_pool.purge,则在使用之前必须特工设置event 5614566(alter session set events '5614566 trace name context forever'),否则dbms_shared_pool.purge将不起作用,这个限制在10.2.0.4以上的版本中已经不存在了。如果认没有安装dbms_shared_pool包的可以执行@?/rdbms/admin/dbmspool.sql


参考《基于Oracle的sql优化》

官方文档:http://docs.oracle.com/cd/E11882_01/appdev.112/e40758/d_shared_pool.htm#ARPLS68077

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

相关推荐


Java Oracle 结果集是Java语言中处理数据库查询结果的一种方式。通常情况下,Java程序会通过JDBC连接Oracle数据库并执行一条查询语句,返回一个ResultSet结果集。ResultSet是一个行集,包含了查询语句的返回结果。在
Java AES和Oracle AES是现代加密技术中最常使用的两种AES加密。在计算机通信领域,AES加密算法是一种十分重要的保密技术,被广泛应用于银行、保险、互联网电子支付等重要场合。
Java是一种广泛应用的编程语言,具备可靠性、安全性、跨平台性等优势,被广泛应用于企业级应用开发。而Oracle11g是一个强大的关系型数据库,由于其优秀的可靠性、安全性和扩展性,已经被广泛应用于企业级应用中。Jav
随着移动互联网的发展,抽奖活动成为了营销活动中不可或缺的组成部分。为了满足移动端用户的需求,我们可以使用jQuery开发移动端大转盘抽奖活动。
Java和Oracle都是在计算机领域应用非常广泛的技术,他们经常被用来搭建高效的软件系统。Java是一种面向对象的编程语言,而Oracle是一种关系型数据库管理系统。Java 和Oracle在应用中的联系非常紧密,它们能够通过相互
Java 是一门非常流行的编程语言,它可以运行于各种操作系统上,而 Oracle 是一个广泛使用的数据库软件。在 Java 对 Oracle 进行操作时,需要使用 Oracle 参数来确保程序正确工作。本文将从 Oracle 参数的定义、分类
随着电子竞技的兴起,越来越多的人开始慕名玩起了王者荣耀。而对于Python爱好者来说,这款游戏也有着很大的吸引力。因为Python可以帮助我们获取并处理游戏数据,从而获得更好的游戏体验。
Java与Oracle在数据处理方面都有着非常重要的地位,而在Java和Oracle的结合中,Integer类型则起到了不可替代的作用。Integer类型是Java中一个非常常用的数据类型,它可以表示范围在-2147483648到2147483647之间的整数
如今,JavaScript已经成为了web开发的必备技能之一,而IE浏览器也是众多开发者最常用的浏览器,那么,如何启用IE浏览器的JavaScript呢?
Java与Oracle是当今软件行业中广泛使用的两个技术。而SP(Stored Procedure)是Oracle数据库中存储过程的组件,可以在Java中调用Oracle数据库中的SP。在开发过程中,Java和Oracle的组合可以方便处理大规模的数据和建