[20220309]查詢x$ksmmem遇到的疑問補充.txt

lfree發表於2022-03-09

[20220309]查詢x$ksmmem遇到的疑問補充.txt

--//在昨天的查詢x$ksmmem遇到的疑問,當天晚上仔細看了早上寫的內容,可能我忽略查詢的順序,補充測試看看.

1.環境:
SYS@book> @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> show array
arraysize 100

SYS@book> show release
release 1102000400
--//sqlplus版本是11.2.0.4.

2.測試:
SYS@book> @ memalloc
MIN(BASEADDR)    MAX(BASEADDR)      GRANULES         MB  GRANFLAGS COMPONENT                        GRANSTATE
---------------- ---------------- ---------- ---------- ---------- -------------------------------- ----------------
0000000060C00000 000000007A000000        102        408          4 DEFAULT buffer cache             ALLOC
000000007A400000 000000007AC00000          3         12          4 java pool                        ALLOC
000000007B000000 000000007B800000          3         12          4 large pool                       ALLOC
000000007BC00000 0000000086400000         43        172          4 shared pool                      ALLOC

--//我沒有貼出memalloc指令碼,實際我的環境oracle記憶體手工設定,不會出現MIN(BASEADDR),MAX(BASEADDR)之間DEFAULT buffer cache出
--//現shared pool或者其他元件的情況.

SYS@book> SELECT rownum ,inst_id,indx,addr, KSMMMVAL FROM X$KSMMEM WHERE addr >= hextoraw('0000000060C00000') and addr<=hextoraw('0000000060C00008');
    ROWNUM    INST_ID       INDX ADDR             KSMMMVAL
---------- ---------- ---------- ---------------- ----------------
         1          1    1572864 0000000060C00000 00
         2          1    1572865 0000000060C00008 00
Elapsed: 00:00:15.44
--//注:開始查詢記憶體元件的前面2條記錄,可以發現需要15秒,比我前面的測試12.XX秒時間要長.
--//我開始的理解addr從低端向高階掃描,遇到滿足條件時(也就是addr在查詢範圍時),再去從某種方式獲取select欄位資訊,
--//這樣獲取INDX,INST_ID不需要太多時間,我僅僅返回2條記錄,其他根本無法滿足查詢條件,我的理解應該查詢更快才對,而實際的測試
--//結果更慢,這也是我感覺oracle的一些演算法有問題的原因.

SYS@book> SELECT rownum ,inst_id,indx,addr, KSMMMVAL FROM X$KSMMEM WHERE addr <=hextoraw('0000000060C00008') and addr >= hextoraw('0000000060C00000');
    ROWNUM    INST_ID       INDX ADDR             KSMMMVAL
---------- ---------- ---------- ---------------- ----------------
         1          1    1572864 0000000060C00000 00
         2          1    1572865 0000000060C00008 00
Elapsed: 00:00:12.59
--//注意看我僅僅將後面的查詢條件換了一個位置,addr <=hextoraw('0000000060C00008')寫在前面,查詢時間就少了將近3秒。

--//看看與select是否相關。
SYS@book> @ desc X$KSMMEM
           Name                            Null?    Type
           ------------------------------- -------- ----------------------------
    1      ADDR                                     RAW(8)
    2      INDX                                     NUMBER
    3      INST_ID                                  NUMBER
    4      KSMMMVAL                                 RAW(8)
--//ADDR在前面。

SYS@book> SELECT rownum ,x$ksmmem.* FROM X$KSMMEM WHERE addr >= hextoraw('0000000060C00000') and addr<=hextoraw('0000000060C00008');
    ROWNUM ADDR                   INDX    INST_ID KSMMMVAL
---------- ---------------- ---------- ---------- ----------------
         1 0000000060C00000    1572864          1 00
         2 0000000060C00008    1572865          1 00
Elapsed: 00:00:15.59

SYS@book> SELECT rownum ,x$ksmmem.* FROM X$KSMMEM WHERE addr <=hextoraw('0000000060C00008') and addr >= hextoraw('0000000060C00000');
    ROWNUM ADDR                   INDX    INST_ID KSMMMVAL
---------- ---------------- ---------- ---------- ----------------
         1 0000000060C00000    1572864          1 00
         2 0000000060C00008    1572865          1 00
Elapsed: 00:00:12.70
--//無關,差異還是出現謂詞條件上。換成between測試看看。

SYS@book> SELECT rownum ,x$ksmmem.* FROM X$KSMMEM WHERE addr between hextoraw('0000000060C00000') and hextoraw('0000000060C00008');
    ROWNUM ADDR                   INDX    INST_ID KSMMMVAL
---------- ---------------- ---------- ---------- ----------------
         1 0000000060C00000    1572864          1 00
         2 0000000060C00008    1572865          1 00
Elapsed: 00:00:15.42
--//15秒。回到前面的情況。

--//SELECT rownum ,x$ksmmem.* FROM X$KSMMEM WHERE addr <=hextoraw('0000000060C00008') and addr >= hextoraw('0000000060C00000');
--//也就是這樣理解,oracle先看條件addr <=hextoraw('0000000060C00008'),然後取出欄位,再看條件addr >= hextoraw('0000000060C00000'),
--//只有這樣才能解析上面看到的現象。兩者執行計劃看到的filter不同。
2 - filter(("ADDR"<=HEXTORAW('0000000060C00008')  AND
       "ADDR">=HEXTORAW('0000000060C00000') ))

2 - filter(("ADDR">=HEXTORAW('0000000060C00000')  AND
    "ADDR"<=HEXTORAW('0000000060C00008') ))


3.附上memalloc.sql指令碼:
$ cat memalloc.sql
col component format a32
select min(BASEADDR), max(BASEADDR), count(1) Granules, sum(a.gransize)/1048576 MB, a.GRANFLAGS, component, a.GRANSTATE
from x$ksmge a, x$kmgsct b
where a.grantype = b.grantype (+)
group by a.GRANFLAGS, component, a.GRANSTATE
order by 1,2;

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/267265/viewspace-2868320/,如需轉載,請註明出處,否則將追究法律責任。

相關文章