过长的In List引起的共享池内存问题

    开发人员经常想用一个长长的In List来作为Where条件, 但这样的语句如果查执行计划不对的话, 很容易造成共享池(Shared Pool)内存问题, 下面是一个拥有40个值的In List的测试. 占用的内存如下所示:

SQL> SELECT HASH_VALUE,SHARABLE_MEM,PERSISTENT_MEM,RUNTIME_MEM
  2  FROM V$SQL WHERE HASH_VALUE IN (1981294536 ,3511787793);

HASH_VALUE SHARABLE_MEM PERSISTENT_MEM RUNTIME_MEM
---------- ------------ -------------- -----------
1981294536        31836           1088        5336
3511787793       171534           1088      127936

    其中1981294536的计划中用的是INLIST ITERATOR方法, 3511787793语句用的是CONCATENATION方法. 源语句如下:

SQL> SELECT HASH_VALUE,SQL_TEXT FROM V$SQL
  2  WHERE HASH_VALUE IN (1981294536 ,3511787793);

HASH_VALUE SQL_TEXT
---------- ----------------------------------------
1981294536 SELECT /* INTEST1_TEST */ /*+ ALL_ROWS *
           /   OBJECT_ID, OBJECT_NAME FROM T_OBJECT
           S WHERE OBJECT_ID IN (   1,2,3,4,5,6,7,8
           ,9,10,11,12,13,14,15,16,17,18,19,20,   2
           1,22,23,24,25,26,27,28,29,30,31,32,33,34
           ,35,36,37,38,39,40)

3511787793 SELECT /* INTEST2_TEST */ /*+ USE_CONCAT
            */   OBJECT_ID, OBJECT_NAME FROM T_OBJE
           CTS WHERE OBJECT_ID IN (   1,2,3,4,5,6,7
           ,8,9,10,11,12,13,14,15,16,17,18,19,20,
            21,22,23,24,25,26,27,28,29,30,31,32,33,
           34,35,36,37,38,39,40)

    如果DBA发现了这样的情况, 应当建议开发人员减少In List的长度, 分为多次执行, 或者确保SQL语句的执行计划是用了INLIST ITERATOR方法.

留言 (4)

解决之道:
String to table/rows

1) Table Function
CREATE OR REPLACE function ABELISTING.str2tbl( p_str in varchar2, p_delimiter in varchar2 default ',' )
return IDTable
pipelined
as
l_str varchar2(5000) default p_str || p_delimiter;
l_n PLS_Integer;
begin
loop
l_n := instr( l_str, p_delimiter );
exit when (nvl(l_n,0) = 0);
pipe row( ltrim(rtrim(substr(l_str,1,l_n-1))) );
l_str := ltrim( substr( l_str, l_n+1 ) );
end loop;
return;
end;
/

2) SQL CONNECT, covnert string to rows.
WITH sq
AS
(
SELECT SUBSTR(x, INSTR(x,',',1,LEVEL)+1, INSTR(x,',',1,LEVEL+1) - INSTR(x,',',1,LEVEL) -1) token
FROM (SELECT ','||l_str||',' x,l_str FROM (SELECT '1,2,3,4' l_str FROM dual))
CONNECT BY LEVEL )
select * from sq;

参考:
AskTomc.om
and

以前还有一些不定个数的in-list语句, 全部否定了, 进行改进.

我的留言有被拒了
因为包含了一个 HTTP URL 链接.

就在 "参考:" 后面,想给你看几个样本>

and ...

是防spam级别设得有些高, 不好意思.

发表留言:

« Previous | Main | Next »

英语900句 | English 900

  • Do you have a computer?
  • 你有计算机吗?
  • Yes, I do.
  • 是的, 我有.
  • He has that book, doesn't he?
  • 他有那本书, 是吗?
  • No, he doesn't.
  • 不, 他没有.
  • Do you have any brothers or sisters?
  • 你有兄弟或姐妹吗?