[20160215]超长sql语句与父子光标.txt

[20160215]超长sql语句与父子光标.txt

--看<oracle内核技术揭秘>提到sql语句不会进入保留池, 要进入保留池,chunk的大小必须大于_shared_pool_reserved_min_alloc。
--而实际上许多sql语句一般最大4096字节。而且这些内存分配的原则是首先从共享池分配,不行并且大于
--shared_pool_reserved_min_alloc才会从保留池申请。

--作者视乎忘记一种特殊情况就是超长sql语句,这样父游标保存sql的语句chunk可以大于4096字节。自己测试这种情况看看。

1.环境:

SYS@book> @ &r/ver1
PORT_STRING                    VERSION        BANNER
------------------------------ -------------- --------------------------------------------------------------------------------
x86_64/Linux 2.4.xx            11.2.0.4.0     Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production

SYS@book> @ &r/hide _shared_pool_reserved_min_alloc
NAME                            DESCRIPTION                                                        DEFAULT_VALUE SESSION_VALUE SYSTEM_VALUE
------------------------------- ------------------------------------------------------------------ ------------- ------------- ------------
_shared_pool_reserved_min_alloc minimum allocation size in bytes for reserved area of shared pool  TRUE          4400          4400

2.建立一个sql语句脚本:
select /*+
zzzzzzzzzzzzz
....
zzzzz
*/ * from dept where deptno=10;

$ wc aa.sql
   70    76 68043 aa.sql
--大小68043字节。

SCOTT@book> @aa.sql

    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK

--查询获得该语句的sql_id=4bm0a97bq61za.

3.查询sql的内存结构:
# cat /home/oracle11g/sqllaji/sharepool/shp4.sql
column N0_6_16 format 9999999
SELECT DECODE (kglhdadr,
               kglhdpar, '父游标句柄地址',
               '子游标句柄地址')
          text,
       kglhdadr,
       kglhdpar,
       substr(kglnaobj,1,40) c40,
       kglobhd0,
       kglobhd6,
       kglobhs0,kglobhs6,kglobt16,
       kglobhs0+kglobhs6+kglobt16 N0_6_16,
           kglobhs0+kglobhs1+kglobhs2+kglobhs3+kglobhs4+kglobhs5+kglobhs6+kglobt16 N20,
           kglnahsh,
           kglobt03
  FROM x$kglob
WHERE kglobt03 = '&1'  or kglhdpar='&1' or kglhdadr='&1';

SYS@book> @ &r/sharepool/shp4 4bm0a97bq61za

TEXT           KGLHDADR         KGLHDPAR         C40                                      KGLOBHD0         KGLOBHD6           KGLOBHS0   KGLOBHS6   KGLOBT16  N0_6_16        N20   KGLNAHSH KGLOBT03
-------------- ---------------- ---------------- ---------------------------------------- ---------------- ---------------- ---------- ---------- ---------- -------- ---------- ---------- -------------
子游标句柄地址 0000000061BE43F8 0000000063ACE5C0 select /*+ zzzzzzzzzzzzzzzzzzzzzzzzzzzzz 000000007C0CE810 000000006473F770       4488      12144      71074    87706      87706 3613591530 4bm0a97bq61za
父游标句柄地址 0000000063ACE5C0 0000000063ACE5C0 select /*+ zzzzzzzzzzzzzzzzzzzzzzzzzzzzz 000000007C0CE900 00                    72736          0          0    72736      72736 3613591530 4bm0a97bq61za

*/

--其他结构应该跟以前的测试一样,可以参考我以前的blog。http://blog.itpub.net/267265/viewspace-1966412/

old   1: SELECT * FROM x$ksmsp WHERE TO_NUMBER ('&1', 'xxxxxxxxxxxxxxxx') between TO_NUMBER(KSMCHPTR, 'xxxxxxxxxxxxxxxx') and TO_NUMBER(KSMCHPTR, 'xxxxxxxxxxxxxxxx')+KSMCHSIZ
new   1: SELECT * FROM x$ksmsp WHERE TO_NUMBER ('0000000063ACE5C0', 'xxxxxxxxxxxxxxxx') between TO_NUMBER(KSMCHPTR, 'xxxxxxxxxxxxxxxx') and TO_NUMBER(KSMCHPTR, 'xxxxxxxxxxxxxxxx')+KSMCHSIZ
ADDR                   INDX    INST_ID   KSMCHIDX   KSMCHDUR KSMCHCOM         KSMCHPTR           KSMCHSIZ KSMCHCLS   KSMCHTYP KSMCHPAR
---------------- ---------- ---------- ---------- ---------- ---------------- ---------------- ---------- -------- ---------- ----------------
00007F50B1279228      24728          1          1          2 KGLHD            0000000063ACE590      68576 recr             80 00

--可以发现KSMCHSIZ=68576.chunk大小68576,而我的sql语句文本长度68043。也就说明sql语句如果sql语句超长有可能分配很大的chunk
--(大于4096).

3.另外建立sql脚本:
--内容与前面相似。

$ wc bb.sql
   1170    1176 1168043 bb.sql

--执行后获得sql_id=ags54g605qs0f.

SYS@book> @ &r/sharepool/shp4 ags54g605qs0f
TEXT           KGLHDADR         KGLHDPAR         C40                                      KGLOBHD0         KGLOBHD6           KGLOBHS0   KGLOBHS6   KGLOBT16  N0_6_16        N20   KGLNAHSH KGLOBT03
-------------- ---------------- ---------------- ---------------------------------------- ---------------- ---------------- ---------- ---------- ---------- -------- ---------- ---------- -------------
子游标句柄地址 000000007C27BD28 0000000063983060 select /*+ zzzzzzzzzzzzzzzzzzzzzzzzzzzzz 0000000061BCC2F8 00000000646A2770       4504      12144    1171074  1187722    1187722 2153472014 ags54g605qs0f
父游标句柄地址 0000000063983060 0000000063983060 select /*+ zzzzzzzzzzzzzzzzzzzzzzzzzzzzz 000000007C27C100 00                  1172736          0          0  1172736    1172736 2153472014 ags54g605qs0f

*/

old   1: SELECT * FROM x$ksmsp WHERE TO_NUMBER ('&1', 'xxxxxxxxxxxxxxxx') between TO_NUMBER(KSMCHPTR, 'xxxxxxxxxxxxxxxx') and TO_NUMBER(KSMCHPTR, 'xxxxxxxxxxxxxxxx')+KSMCHSIZ
new   1: SELECT * FROM x$ksmsp WHERE TO_NUMBER ('0000000063983060', 'xxxxxxxxxxxxxxxx') between TO_NUMBER(KSMCHPTR, 'xxxxxxxxxxxxxxxx') and TO_NUMBER(KSMCHPTR, 'xxxxxxxxxxxxxxxx')+KSMCHSIZ
ADDR                   INDX    INST_ID   KSMCHIDX   KSMCHDUR KSMCHCOM         KSMCHPTR           KSMCHSIZ KSMCHCLS   KSMCHTYP KSMCHPAR
---------------- ---------- ---------- ---------- ---------- ---------------- ---------------- ---------- -------- ---------- ----------------
00007F50B144E228      24994          1          1          2 KGLHD            0000000063983030    1168576 recr             80 00

--可以发现chunk的大小占用1168576。1168576/1024/1024=1.1144M

4.是否通过这个可以确定sql语句也可以进入保留池呢?

--修改bb.sql脚本:
select /*+ &&1
zzzzzzzzzzzzzzzz
...
zzzzz
&&1 */ * from dept where deptno= &&1;

--这样每次不同的sql语句都不一样。

#! /bin/bash
for i in $(seq 500)
do
    echo @bb.sql $i
done
--执行它产生执行脚本cc.sql。

--执行cc.sql。

--打开另外的会话不断执行:

SYS@book> SELECT * FROM x$ksmsp WHERE KSMCHSIZ=1168576 and KSMCHCLS like '%recr%';
ADDR                   INDX    INST_ID   KSMCHIDX   KSMCHDUR KSMCHCOM         KSMCHPTR           KSMCHSIZ KSMCHCLS   KSMCHTYP KSMCHPAR
---------------- ---------- ---------- ---------- ---------- ---------------- ---------------- ---------- -------- ---------- ----------------
00007F9C119523F8       9509          1          1          2 KGLHD            00000000656B1AE0    1168576 recr             80 00
00007F9C11952190       9516          1          1          2 KGLHD            0000000065593DC0    1168576 recr             80 00
00007F9C11951F28       9523          1          1          2 KGLHD            00000000654760A0    1168576 recr             80 00

SYS@book> SELECT * FROM x$ksmsp WHERE KSMCHSIZ=1168576 and KSMCHCLS like '%recr%';
ADDR                   INDX    INST_ID   KSMCHIDX   KSMCHDUR KSMCHCOM         KSMCHPTR           KSMCHSIZ KSMCHCLS   KSMCHTYP KSMCHPAR
---------------- ---------- ---------- ---------- ---------- ---------------- ---------------- ---------- -------- ---------- ----------------
00007F9C119508E0       9510          1          1          2 KGLHD            00000000656B1AE0    1168576 recr             80 00
00007F9C11952660       9517          1          1          2 KGLHD            0000000065593DC0    1168576 recr             80 00
00007F9C119523F8       9524          1          1          2 KGLHD            00000000654760A0    1168576 recr             80 00
00007F9C11951DC8       9542          1          1          2 KGLHD            0000000065206638    1168576 recr             80 00
00007F9C11951B60       9549          1          1          2 KGLHD            00000000650E8918    1168576 recr             80 00
..

SYS@book> SELECT * FROM x$ksmsp WHERE KSMCHSIZ=1168576 and KSMCHCLS like '%recr%';
no rows selected

--到最后竟然没有查询结果。顺便从共享池找到一条相似sql语句看看。

SYS@book> @ &r/sharepool/shp4 0000000061A67A00
TEXT           KGLHDADR         KGLHDPAR         C40                                      KGLOBHD0         KGLOBHD6           KGLOBHS0   KGLOBHS6   KGLOBT16  N0_6_16        N20   KGLNAHSH KGLOBT03
-------------- ---------------- ---------------- ---------------------------------------- ---------------- ---------------- ---------- ---------- ---------- -------- ---------- ---------- -------------
子游标句柄地址 0000000061B76578 0000000061A67A00 select /*+ 485 zzzzzzzzzzzzzzzzzzzzzzzzz 0000000061982F28 000000007CFEC770       4488      12144    1171084  1187716    1187716 4105512445 dw1zwymuba9gx
父游标句柄地址 0000000061A67A00 0000000061A67A00 select /*+ 485 zzzzzzzzzzzzzzzzzzzzzzzzz 00000000618DC7A8 00                  1172737          0          0  1172737    1172737 4105512445 dw1zwymuba9gx
*/

old   1: SELECT * FROM x$ksmsp WHERE TO_NUMBER ('&1', 'xxxxxxxxxxxxxxxx') between TO_NUMBER(KSMCHPTR, 'xxxxxxxxxxxxxxxx') and TO_NUMBER(KSMCHPTR, 'xxxxxxxxxxxxxxxx')+KSMCHSIZ
new   1: SELECT * FROM x$ksmsp WHERE TO_NUMBER ('0000000061A67A00', 'xxxxxxxxxxxxxxxx') between TO_NUMBER(KSMCHPTR, 'xxxxxxxxxxxxxxxx') and TO_NUMBER(KSMCHPTR, 'xxxxxxxxxxxxxxxx')+KSMCHSIZ
ADDR                   INDX    INST_ID   KSMCHIDX   KSMCHDUR KSMCHCOM         KSMCHPTR           KSMCHSIZ KSMCHCLS   KSMCHTYP KSMCHPAR
---------------- ---------- ---------- ---------- ---------- ---------------- ---------------- ---------- -------- ---------- ----------------
00007F9C11A18C60       6516          1          1          2 KGLHD            0000000061A679D0      18304 recr             80 00

--哦!KSMCHSIZ=18304.说明内存不足可以拆分多段。也没有进入保留池。

--太复杂放弃!

时间: 2024-09-20 12:29:20

[20160215]超长sql语句与父子光标.txt的相关文章

[20170703]SQL语句分析执行过程.txt

[20170703]SQL语句分析执行过程.txt --//正常sql select语句执行需要这些过程,create cursor,parse,execute and fetch. --//dml估计缺少fetch步骤.参考vage的书写的例子,原书的例子存在问题,理解如下脚本对于sql语句如何执行很有益处. --//当然正常的编程很少有人这样写代码的. DECLARE    mcur     NUMBER;    mstat    NUMBER;    v_name   VARCHAR2 (

[20151209]一条sql语句的优化(续).txt

[20151209]一条sql语句的优化(续).txt http://blog.itpub.net/267265/viewspace-1852195/ --上次提到其中1条sql语句: 1.环境: SYSTEM@192.168.99.105:1521/dbcn> @ver1 PORT_STRING                    VERSION        BANNER ------------------------------ -------------- -------------

[20140210]一条sql语句的优化(11g).txt

  [20140210]一条sql语句的优化(11g).txt 今天下午看生产系统数据库,无意中发现一个错误,同时优化也有点小问题,写一个测试脚本. 1.建立测试环境: SCOTT@test> @ver BANNER -------------------------------------------------------------------------------- Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 -

[20120104]稳定一条sql语句的执行计划.txt

[20120104]稳定一条sql语句的执行计划.txt http://www.itpub.net/thread-1495845-1-1.htmlhttp://space.itpub.net/267265/viewspace-723066 ORACLE8I升级11G R2后,查询系统视图特别慢 我的测试版本:SQL> select * from v$version where rownumBANNER------------------------------------------------

[20120327]toad与sqlplus下执行sql语句的一个细节.txt

TOAD是一个很好的图形化oracle管理工具,昨天在解决一个问题时遇到了一些细节问题,实际上我以前就知道,现在把它写下来: 我使用toad版本是9.6.0.27. 1.在sqlplus下执行如下: SQL> select /*+ zzzz */ * from dept where deptno=10;     DEPTNO DNAME          LOC ---------- -------------- -------------         10 ACCOUNTING     N

[20161228]sql语句父子游标的堆转储2.txt

[20161228]sql语句父子游标的堆转储2.txt --以前仅仅看了父游标堆0的堆转储,链接:http://blog.itpub.net/267265/viewspace-2076605/ --尽然当时没有做子游标堆0,6的堆转储,今天测试看看. 1.环境: SYS@book> @ &r/ver1 PORT_STRING                    VERSION        BANNER ------------------------------ -----------

[20160407]sql语句父子游标的堆转储.txt

[20160407]sql语句父子游标的堆转储.txt --昨天晚上看一些文档,发现可以通过alter session set events 'immediate trace name heapdump_addr level 2,addr 0xXXXXXXXX'; --后面加堆地址,转储里面的内容.自己测试看看: --另外补充说明一下: 我看了jonathan lewis <oracle核心技术> 里面提到ds 应该是 data segment. 1.环境: SCOTT@book> @

[20161230]查看父游标中sql语句.txt

[20161230]查看父游标中sql语句.txt --上午巡检完,无聊,测试使用oradebug下查看sql语句在父游标中的内容.sql语句在执行第一次硬解析时生成父子游标,其中父游标chunk --中保存sql语句,测试通过oradebug下如何查看: 1.环境: SCOTT@book> select * from dept where deptno=10;     DEPTNO DNAME          LOC ---------- -------------- -----------

缓存-oracal sql语句服务器执行时间超长,本地很快!不知道原因,求oracal大神围观!

问题描述 oracal sql语句服务器执行时间超长,本地很快!不知道原因,求oracal大神围观! 贴上sql(这个sql大家不用太用心看,语句不是问题): insert into pms_consump SELECT DISTINCT DECODE (nvl(trans.transamt,0), 0, '0.00', TRUNC (nvl(trans.transamt,0) / 100, 2)) AS transamt, nvl(trans.transamt,0) AS hiddenTran