tom 9I-10G的sga的多快取池 多塊和dual表的一點分析

dotaddjj發表於2012-02-14

Sga共享記憶體區,在nomount階段已經分配,每個oracle程式都會訪問其中的某一點。在unix作業系統上,sga是一個物理實體,程式可以附加到這段獨立的記憶體上。

[oracle@localhost ~]$ ipcs -m|grep ora

0x01b9ced8 65537 oracle 640 1612709888 771

Windows上,oracle會作為一個地址空間單個程式執行,sga將作為專用記憶體分配給oracle.exe程式,無法檢視sga分配記憶體

固定sga

固定sgasga一個元件,其大小跟平臺版本有關,安裝資料庫時,固定sga會編譯到二進位制執行檔案中。固定sga中儲存了各sga元件的變數和引數,通常很小無法調整用於自啟sga定位其他元件。(可以想象為bootstrap$啟動資料庫一樣,用於在記憶體中先建立bootstrap$表然後透過物理檔案插入資料到bootstrap$中初始化資料字典。)

Log_buffer

重做日誌快取區用於儲存redo logbuffer,然後在事務提交,日誌切換,log_buffer達到1MB或者1/3,每三秒一次時都會觸發LGWRlog_buffer寫入redo log

由於LGWR頻繁的寫入,一般設定較大的log_buffer意義不大,不過對於大量併發事務的大型系統,較大的log_buffer更為合理,一個大型事務中會產生很多redo,此時別的session的事務也可能在執行,較大的log_buffer更能滿足這種併發大事務系統。

SQL> alter system set log_buffer=1 scope=spfile;

系統已更改。

SQL> startup force;

ORACLE 例程已經啟動。

Total System Global Area 373293056 bytes

Fixed Size 1249080 bytes

Variable Size 117440712 bytes

Database Buffers 251658240 bytes

Redo Buffers 2945024 bytes

資料庫裝載完畢。

資料庫已經開啟。

SQL> show parameter log_buffer;

NAME TYPE VALUE

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

log_buffer integer 2899456

log_buffer的預設最小大小受os限制,即使設定1位元組log_bufferlog_buffer依然根據os選擇合適的log_buffer

資料字典查詢的hint rbo

select * from dba_objects where data_object_id in

(select data_object_id from dba_objects

group by data_object_id having count(*)>1)

上述sql語句在cbocost 365,由於是本機測試庫,相對硬體環境較差,特別是磁碟I/O效能上,sql語句長時間未反應,發現執行計劃中走了obj$基表的全表掃描,這個基表相對比較大,試試hint /*+rule*/強制走rborbo下會預設索引為最高階別,obj$表選擇了索引,sql語句馬上就有相應執行結果,由於對資料字典無法分析,oracle可能無法高效利用索引,強制hint rbo相對與無法分析統計的資料字典執行效率大幅提升!這也提醒在cbo下統計分析的重要性!

Oracle 10gdual虛表的兩個有意思的查詢

SQL> select sysdate from dual;

SYSDATE

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

14-2 -12

執行計劃

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

Plan hash value: 1388734953

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

| Id | Operation | Name | Rows | Cost (%CPU)| Time |

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

| 0 | SELECT STATEMENT | | 1 | 2 (0)| 00:00:01 |

| 1 | FAST DUAL | | 1 | 2 (0)| 00:00:01 |

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

統計資訊

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

1 recursive calls

0 db block gets

0 consistent gets

0 physical reads

0 redo size

412 bytes sent via SQL*Net to client

385 bytes received via SQL*Net from client

2 SQL*Net roundtrips to/from client

0 sorts (memory)

0 sorts (disk)

1 rows processed

SQL> select * from dual;

D

-

X

執行計劃

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

Plan hash value: 272002086

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

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

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

| 0 | SELECT STATEMENT | | 1 | 2 | 2 (0)| 00:00:01 |

| 1 | TABLE ACCESS FULL| DUAL | 1 | 2 | 2 (0)| 00:00:01 |

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

統計資訊

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

24 recursive calls

0 db block gets

6 consistent gets

3 physical reads

0 redo size

404 bytes sent via SQL*Net to client

385 bytes received via SQL*Net from client

2 SQL*Net roundtrips to/from client

0 sorts (memory)

0 sorts (disk)

1 rows processed

看出在oracle 10g後對dual表做了調整,當不實際查詢dual表的資料時,oracle會直接做函式等查詢,而沒有實際訪問dual表,對於大量使用dual表的系統,減少大量一致性讀和物理讀次數。

多快取池技術:

除了一般的預設快取池db cacheoracle8I又推出了db_keep_cachedb_recycle_cache多快取技術,db_keep_cache池用於儲存希望一直儲存的塊,db_recycle_cache用於臨時的大塊,而防止隨機訪問大塊導致快取區大量重新整理輸出。

多快取技術一般是作為一種低階的精細的調優手段,而且多快取池之間無法共享,建立段時需要設定儲存的快取池,不然會儲存在預設快取池中,這也增加了管理的難度。

同樣在oracle 9I開始,除了原先的多快取池,資料庫內還可以有多個不同的資料塊大小。

設定非預設塊快取池大小

Alter system set db_4K_cache_size=10m

然後建立非預設塊的表空間

Create tablespace test_4k datafile size 50M autoextend on 10M

Blocksize 4K

注意這裡需要先制定非預設資料塊大小的快取池大小,然後再建立相應的表空間。跟多快取池技術一樣,非預設塊也為資料庫的管理增加了複雜性,主要是用作可傳輸表空間技術,將資料檔案在資料庫之間傳輸,而一般不用做調優,倒是可以用在一些特殊情況下,例如混合系統中,既需要事務處理也需要事務分析。

共享池和large pool

儲存sql pl/sql解析執行計劃和資料字典的共享記憶體結構,共享池一般儲存相對較小的記憶體塊chunk

大池用於大塊記憶體分配,是一個回收型的記憶體空間,一般不重用,如果把大塊記憶體儲存在共享池中,會導致共享池中部分可用記憶體老化,而實際上大塊記憶體也不需要快取。

大池主要用於:共享伺服器下在sga中分配uga區(共享伺服器連結下uga一般很大),語句並行執行,rman備份下的磁碟I/O緩衝

[@more@]

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

相關文章