您的位置:首页 > 数据库

利用REMOVE_CONSTANTS函数,查询共享池中哪些SQL没有绑定变量

2013-11-08 23:34 267 查看
首先创建一个表,用于存放整理过的数据:

SQL> create table t1 as select sql_text from v$sqlarea;

 

Table created

给表t1增加一个字段:

SQL> alter table t1 add sql_text_wo_constants varchar2(1000);

 

Table altered

创建函数remove_constants;

create or replace function
remove_constants( p_query in varchar2 ) return varchar2
as
l_query long;
l_char varchar2(1);
l_in_quotes boolean default FALSE;
begin
for i in 1 .. length( p_query )
loop
l_char := substr(p_query,i,1);
if ( l_char = '''' and l_in_quotes )
then
l_in_quotes := FALSE;
elsif ( l_char = '''' and NOT l_in_quotes )
then
l_in_quotes := TRUE;
l_query := l_query || '''#';
end if;
if ( NOT l_in_quotes ) then
l_query := l_query || l_char;
end if;
end loop;
l_query := translate( l_query, '0123456789', '@@@@@@@@@@' );
for i in 0 .. 8 loop
l_query := replace( l_query, lpad('@',10-i,'@'), '@' );
l_query := replace( l_query, lpad(' ',10-i,' '), ' ' );
end loop;
return upper(l_query);
end;


将v$sql视图中的数据用remove_constants处理后,更新到t1表中:

SQL> update t1 set sql_text_wo_constants = remove_constants(sql_text);

 

239 rows updated

查出除了谓语条件不同的sql语句和他们的执行次数,在这里是查询sql没有被重用超过100次的sql语句:

SQL> select sql_text_wo_constants,count(*) from t1 group by sql_text_wo_constants having count(*) > 100 order by 2;

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

以下是一个测试的例子,我们使用一个循环执行1000次某条SQL,每次执行只是谓语不用(即不用绑定变量)

SQL> create table t as select rownum rm from dba_objects;

循环1000次这个sql

begin

  for i in 1..1000 loop

    execute immediate 'select * from t where rm='||i;

    end loop;

end;

SQL> create table t1 as select sql_text from v$sqlarea;

 

Table created

 

SQL> alter table t1 add sql_text_wo_constants varchar2(1000);

 

Table altered

 

SQL> update t1 set sql_text_wo_constants = remove_constants(sql_text);

 

372 rows updated

SQL> select sql_text_wo_constants,count(*) from t1 group by sql_text_wo_constants having count(*) > 100 order by 2;

 

SQL_TEXT_WO_CONSTANTS                                                              COUNT(*)

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

SELECT * FROM T WHERE RM=@                                                              146

 

不知道为什么我查出来不是1000次......

**你可以去清一下shared_pool(alter system flush shared_pool)再去做这个实验
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐