[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.說明記憶體不足可以拆分多段。也沒有進入保留池。
--太複雜放棄!
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/267265/viewspace-1989081/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- [20160407]sql語句父子游標的堆轉儲.txtSQL
- [20161228]sql語句父子游標的堆轉儲2.txtSQL
- [20220117]超長sql語句.txtSQL
- Oracle - 共享遊標、父子游標、硬軟解析Oracle
- [20220120]超長sql語句補充4.txtSQL
- [20220119]超長sql語句補充3.txtSQL
- [20240320]空格與sqlpus的sql語句.txtSQL
- [20150403]修正sql語句.txtSQL
- [20121016]字串長度與繫結變數的子游標.txt字串變數
- PL/SQL與DDL語句SQL
- [20161230]檢視父遊標中sql語句.txtSQL
- Oracle sql with 語句語法與例子OracleSQL
- input 獲取游標位置與設定游標位置
- 1224關於共享池4SQL記憶體結構父子游標補充SQL記憶體
- [20170103]sql語句過載.txtSQL
- PLSQL Language Referenc-PL/SQL靜態SQL-靜態SQL的描述-游標-顯式游標SQL
- PLSQL Language Referenc-PL/SQL靜態SQL-游標變數-建立游標變數SQL變數
- MySql與Sql Server Update語句MySqlServer
- 1229關於共享池4-SQL記憶體結構父子游標補充3SQL記憶體
- 20150213關於共享池4-SQL記憶體結構父子游標SQL記憶體
- mysql sql語句執行超時設定MySql
- [20210812]測試sql語句子游標的效能.txtSQL
- PLSQL Language Referenc-PL/SQL靜態SQL-游標變數-游標變數賦值SQL變數賦值
- SQL語句與正規表示式SQL
- SQL Profiles與語句最佳化SQL
- SQL語句SQL
- Java中如何解析SQL語句、格式化SQL語句、生成SQL語句?JavaSQL
- winform之手繪矩形及游標字串與游標關聯顯示ORM字串
- [20170703]SQL語句分析執行過程.txtSQL
- [20131204]sql語句優化.txtSQL優化
- [20151221]sql語句優化.txtSQL優化
- [20141013]奇怪的sql語句.txtSQL
- [20150527]跟蹤單個sql語句.txtSQL
- [20121101]tkprof抽取sql語句.txtSQL
- [20240607]PL/SQL中sql語句的註解.txtSQL
- PL/SQL第三章--游標SQL
- MyBatis標籤實現的動態SQL語句MyBatisSQL
- SQL語句的解析過程 遊標週期SQL