oracle查看緩存
『壹』 oracle keep pool會不會自動緩存cache的表數據的更改
ORACLE緩存是把ORACLE近期查看的語句防止在ORACLE設定的緩存當中
ORACLE緩存表是把表某個表放置在緩存當中,緩存是ORACLE在內存中的一個分區
表緩存的設定
oracle中如何將表緩存到內存中
由於在一些靜態資料表在資料庫中被頻繁的訪問,所以可以考慮將這些數據量不大的表緩存到內存當中。
將fisher表緩存到內存中
alter table fisher cache;方法一
2)alter table fisher storage(buffer_pool keep);方法二
--取消緩存
1)alter table fisher nocache;
2)alter table fisher storage(buffer_pool default);
select table_name,OWNER,cache,buffer_pool from dba_tables where table_name='FISHER'; --查看是否緩存
select * from dba_segments where segment_name='FISHER' ; --查看錶大小
方法一: cache是將表緩存到share pool 中,該操作直接將表緩存的熱端,受LRU演算法控制。
方法二:將表緩存到一個固定的內存空間中,默認情況下buffer_pool空間為0,。需手動設置空間大小。
設置空間大小:alter system set db_keep_cache_size=50M scope=both sid=『*';
--表緩存
alter table table_name cache = alter table table_name storage(buffer_pool default);
alter table table_name storage(buffer_pool keep);
--已經加入到KEEP區的表想要移出緩存,使用
alter table table_name nocache;
--查看哪些表被放在緩存區 但並不意味著該表已經被緩存
select table_name from dba_tables where buffer_pool='keep';
--查詢到該表是否已經被緩存
select table_name,cache,buffer_pool from user_TABLES where cache like '%Y';
--查詢當前用戶下表的情況
select table_name,cache,buffer_pool from user_TABLES;
--對於普通LOB類型的segment的cache方法
alter table t2 modify lob(c2) (storage (buffer_pool keep) cache);
--取消緩存
alter table test modify lob(address) (storage (buffer_pool keep) nocache);
keep Buffer Pool
Keep Buffer Pool 的作用是緩存那些需要經常查詢的對象但又容易被默認緩沖區置換出去的對象,按慣例,Keep pool設置為合理的大小,以使其中存儲的對象不再age out,也就是查詢這個對象的操作不會引起磁碟IO操作,可以極大地提高查詢性能。
默認的情況下 db_keep_cache_size=0,未啟用,如果想要啟用,需要手工設置db_keep_cache_size的值,設置了這個值之後 db_cache_size 會減少。
並不是我們設置了keep pool 之後,熱點表就一定能夠緩存在 keep pool ,keep pool 同樣也是由LRU 鏈表管理的,當keep pool 不夠的時候,最先緩存到 keep pool 的對象會被擠出,不過與default pool 中的 LRU 的管理方式不同,在keep pool 中表永遠是從MRU 移動到LRU,不會由於你做了FTS而將表緩存到LRU端,在keep pool中對象永遠是先進先出。當oracle發現你的表太太,大過你設定keep pool的大小是,根本就不會放到keep池中去的(如keep pool設定100M ,設定的用戶緩存的表為200M)。可以用select segment_name from dba_segments where BUFFER_POOL = 'KEEP';語句查看便知。
10g中SGA自動管理,ORACLE並不會為我們管理keep pool ,ORACLE只會管理default pool。
查看 keep pool 大小
SQL> select component,current_size from v$sga_dynamic_components
2 where component='KEEP buffer cache';
COMPONENT CURRENT_SIZE
---------------------------------------------------------------- ------------
KEEP buffer cache 0
手動分配keep pool
SQL> show parameter keep
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
buffer_pool_keep string
control_file_record_keep_time integer 7
db_keep_cache_size big integer 0
SQL> alter system set db_keep_cache_size=10m;
系統已更改。
SQL> show parameter keep
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
buffer_pool_keep string
control_file_record_keep_time integer 7
db_keep_cache_size big integer 16M這里keep pool 16M,可我前面設置命名是10m了?
SQL> select component,current_size from v$sga_dynamic_components where component='KEEP buffer cache';
COMPONENT CURRENT_SIZE
---------------------------------------------------------------- ------------
KEEP buffer cache 16777216 這里keep pool 16M,可我前面設置命名是10m了?
查看keep pool剩餘大小
SQL> select p.name,a.cnum_repl "total buffers",a.anum_repl "free buffers" from x$kcbwds a, v$buffer_pool p
2 where a.set_id=p.LO_SETID and p.name='KEEP';
NAME total buffers free buffers
-------------------- ------------- ------------
KEEP 1984 1984
可以看到沒有使用過keep 池
指定table的緩存池
SQL>create table test as select * from dba_objects;;
Table created.
SQL> alter table test storage(buffer_pool keep);
Table altered.
或者是
create table test storage(buffer_pool keep) as select * from dba_objects;
查看放入Keep的對象
SQL> select segment_name from dba_segments where BUFFER_POOL = 'KEEP';
SEGMENT_NAME
--------------------------------------------------------------------------------
TEST
SQL> /
NAME total buffers free buffers
-------------------- ------------- ------------
KEEP 1984 1962 可以看到使用了22個block
查看以上的表佔用了db_keep_cache_size 多大的空間?
SQL> select substr(sum(b.NUMBER_OF_BLOCKS) * 8129 / 1024 / 1024, 1, 5) || 'M'
from (SELECT o.OBJECT_NAME, COUNT(*) NUMBER_OF_BLOCKS
FROM DBA_OBJECTS o, V$BH bh, dba_segments dd
WHERE o.DATA_OBJECT_ID = bh.OBJD
AND o.OWNER = dd.owner
and dd.segment_name = o.OBJECT_NAME
and dd.buffer_pool != 'DEFAULT'
GROUP BY o.OBJECT_NAME
ORDER BY COUNT(*)) b; 2 3 4 5 6 7 8 9
SUBSTR(SUM(
-----------
3.643M
SQL> select table_name,cache,blocks from dba_tables where wner='ROBINSON' and buffer_pool='KEEP';
TABLE_NAME CACHE BLOCKS
------------------------------ -------------------- ----------
TEST N 22
可以看到這個表的 22個block 全部cache 到 keep pool ,這里的cache 欄位表明 這個表 還沒有使用 這個命令 alter table test cache,如果 使用了 alter table test cache ,命令,那麼 N 將變成Y
總結:如果表經常使用,而且表較小,可以設置 keep pool ,將table 全部 cache 到 keep pool, keep pool 要麼 全部 cache 一個table ,要麼不cache 。所以,對於大表來說,如果想要 cache 到 keep pool, 就需要設置 較大的 keep pool ,以容納大的 table,否者就沒有作用了。
Recycle Buffer Pool
Recycle Buffer Pool正好相反。Recycle Buffer Pool用於存儲臨時使用的、不被經常使用的較大的對象,這些對象放置在Default Buffer Pool顯然是不合適的,這些塊會導致過量的緩沖區刷新輸出,而且不會帶來任何好處,因為等你想要再用這個塊時,它可已經老化退出了緩存。要把這些段與默認池和保持池中的段分開,這樣就不會導致默認池和保持池中的塊老化而退出緩存。
SQL> show parameter recyc
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
buffer_pool_recycle string
db_recycle_cache_size big integer 12M
recyclebin string on
如何將一個表放入Recycle Buffer Pool中:
SQL> alter table test1 storage (buffer_pool recycle);
Table altered.
很多老的文檔會提及buffer_pool_keep和buffer_pool_recycle 這兩個參數,其實這兩個參數已經廢棄,由新參數db_keep_cache_size和db_recycle_cache_size 替代:
SQL>select ISDEPRECATED,NAME from v$parameter where name = 'buffer_pool_keep';
ISDEP NAME
----- -----------------
TRUE buffer_pool_keep
=======================================================================================
--表緩存
alter table ..... storage(buffer_pool keep);
--查看哪些表被放在緩存區 但並不意味著該表已經被緩存
select table_name from dba_tables where buffer_pool='keep';
--查詢到該表是否已經被緩存
select table_name,cache,buffer_pool from user_TABLES where cache like '%Y';
--已經加入到KEEP區的表想要移出緩存,使用
alter table table_name nocache;
--批量插入ORACLE建議用
insert all into ...insert into ...select 1 from al;
insert all into ... insert into ...select 1 from al;
--查詢當前用戶下表的情況
select table_name,cache,buffer_pool from user_TABLES;
--對於普通LOB類型的segment的cache方法
alter table t2 modify lob(c2) (storage (buffer_pool keep) cache);
--取消緩存
alter table test modify lob(address) (storage (buffer_pool keep) nocache);
--查詢段
select segment_name,segment_type,buffer_pool from user_segments;
--對基於CLOB類型的對象的cache方法
alter table lob1 modify lob(c1.xmldata) (storage (buffer_pool keep) cache);
--查詢該用戶下所有表內的大欄位情況
select column_name,segment_name from user_lobs;
來一段Tom關於Multiple Buffer Pools的解釋,講解得很清楚:
實際上,這3 個池會以大體相同的方式管理塊;將塊老化或緩存的演算法並沒有根本的差異。這樣做的目標是讓DBA 能把段聚集到「熱」區(hot)、「溫」區(warm)和「不適合緩存」區(do not care to cache)。
理論上講,默認池中的對象應該足夠熱(也就是說,用得足夠多),可以保證一直呆在緩存中。緩存會把它們一直留在內存中,因為它們是非常熱門的塊。可能還有一些段相當熱門,但是並不太熱;這些塊就作為溫塊。這些段的塊可以從緩存刷新輸出,為不常用的一些塊(「不適合緩存」塊)騰出空間。為了保持這些溫段的塊得到緩存,可以採取下面的某種做法:將這些段分配到保持池,力圖讓溫塊在緩沖區緩存中停留得更久。將「不適合緩存」段分配到回收池,讓回收池相當小,以便塊能快速地進入緩存和離開緩存(減少管理的開銷)。這樣會增加DBA 所要執行的管理工作,因為要考慮3 個緩存,要確定它們的大小,還要為這些緩存分配對象。還要記住,這些池之間沒有共享,所以,如果保持池有大量未用的空間,即使默認池或回收池空間不夠用了,保持池也不會把未用空間交出來。總之,這些池一般被視為一種非常精細的低級調優設備,只有所有其他調優手段大多用過之後才應考慮使用。
按以上步驟把表storage到keep pool中,然後調用alter system flush buffer_cache清空緩存,再全表掃描該表並打開執行計劃跟蹤,發現有physical reads,如下:
第一次執行計劃如下:
----------------------------------------------------------
0 recursive calls
0 db block gets
253 consistent gets
251 physical reads
0 redo size
520 bytes sent via SQL*Net to client
469 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
第二次執行計劃如下:
----------------------------------------------------------
0 recursive calls
0 db block gets
253 consistent gets
0 physical reads
0 redo size
520 bytes sent via SQL*Net to client
469 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
不知道是否可以這樣理解:對於storage到keep pool中的表,第一次會直接physical reads 到keep pool中,下次就直接從keep pool中讀了。flush buffer_cache會清空keep pool,這個試驗就可以證明。
像上面這樣連續執行2次再看執行計劃,和不設置keep pool時的執行計劃應該一樣的,因為讀第二次時,也是從default cache中讀。但是當我們多讀幾個大表到buffer cache後,也就是替換原來從default cache中讀取的數據後,再去讀放入keep中的表時,就會發現keep確實起作用了,唉,終於明白怎麼一回事,害得我為flush buffer導致keep中的表也phisical郁悶了半天。
ORACLE緩存設置
Oracle緩存由兩個參數控制SGA_TARGET和PGA_AGGREGATE_TARGET,設置了這兩個參數,其他的基本內存部分都由Oracle自動配置為最優值,這也是Oracle推薦的方式。
SGA_TARGET 和PGA_AGGREGATE_TARGET是動態參數,可以在不重啟資料庫的情況下修改。但是SGA_TARGET受限於 sga_max_size,SGA_TARGET不能超過sga_max_size,所以要增大sga_target先要增大sga_max_size,而sga_max_size是靜態參數,修改sga_max_size必須重啟Oracle。
所以修改sga_target和pga_aggregate_target的過程如下:
1、修改sga_max_size
SQL>ALTER SYSTEM SET sga_max_size=4g scope=spfile;
2、重啟Oracle
3、設置參數sga_target和pga_aggregate_target,
alter system set sga_target=4G;
alter system set pga_aggregate_target=1g;
如果使用的是10g,已經是ASM, oracle會根據統計的信息,自動的來調整你的內存組件的大小,你只需要設置sga_target即可。當然你可以手動設置 db_cache_size,如果設置了的話,Oracle會在自動調整內存大小的時候把這個作為db_cache_size的最小值。
對於sga_target,在動態修改的時候,最大值不能操過sga_max_size, 如果是用scope=spfile這個方式來修改可以超過sga_max_size,應該此時sga_max_size也跟著變大了,如果超過的話。
Oracle 對資料庫的cache有他自己的計算的,10g以後,內存是動態的根據對你使用系統的統計來進行調整的,如果出現問題,這塊不是原因,你之所以db cache還沒有上去,可能是訪問的數據比較少,不過你加大db_cache_size的值,會保留這個內存空間的,但是也是一樣的,數據 load到內存里,才看得到變化。
數據訪問是什麼樣的訪問,你的系統是OLAP還是OLTP,這些應用上的東西對你的決定也有影響的,要謹記,資料庫的優化和維護,不僅僅是DBA來做的。如果是到了只能通過DBA來做這一步的話,就相當於看病已經到了拿手術刀這一步了。你的改變帶來的風險和代價最高。
要想減少磁碟讀,只能增大內存的使用.樓主可以看看這個視圖v$db_cache_size,並執行下面的查詢:
select block_size, size_for_estimate, size_factor, estd_physical_read_factor, estd_physical_reads from v$db_cache_advice;
Oracle在這個視圖中針對db_cache_size的大小會給出一些建議。
下面解釋幾個列的含義
size_for_estimate:估計的cache size大小
size_factor: 估計的cache size大小與當前大小的比值
estd_physical_reads:在估計的cache size大小情況下,會產生的物理讀數量
estd_physical_read_factor:估計的物理讀數量與當前物理讀數量的比值。
例子:
SIZE_FOR_ESTIMATE SIZE_FACTOR ESTD_PHYSICAL_READ_FACTOR ESTD_PHYSICAL_READS
『貳』 ORACLE 資料庫緩沖區緩存與共享池SQL查詢和PL/SQL函數結果緩存的區別
1、數團咐陵據庫緩沖區DB_BUFFER只能緩存訪問過的BLOCK,部分解決了物理讀的問題,查詢仍然需要大量的邏輯讀。
2、SQL緩存結果集/*+RESULT_CACHE*/它緩存的是查詢的結果。不在需要大量的邏輯讀,不在需要任何的復雜計算,而是直接將已經緩存的結果返回。
3、對於採用了RESULT_CACHE的函數,Oracle自動將函數的返簡胡回結果緩存,下次執行的時候,不會實際執行函數,而是直接返回結果。塌戚由於緩存的結果存儲在SGA中,因此所有的會話可以共享這個結果。
『叄』 如何查看ORACLE把哪些表緩存表到內存了
java">SQL>showuser
Useris"SYS"
SQL>selectowner,object_idfromdba_objectswhereobject_name='A';
OWNEROBJECT_ID
----------------------------------------
ROME60026
SQL>selectcount(*)fromx$bhwhereobj=60026;
COUNT(*)
----------
0
SQL>select*fromrome.a;
ID
--------------------
10.100
10.110
10.111
SQL>selectcount(*)fromx$bhwhereobj=60026;
COUNT(*)
----------
6
SQL>selectcount(*)fromx$bhwhereobj=60026andstate=1;
COUNT(*)
----------
6
SQL>altersystemflushbuffer_cache;
Systemaltered
SQL>selectcount(*)fromx$bhwhereobj=60026andstate=1;
COUNT(*)
----------
0
SQL>select*fromrome.a;
ID
--------------------
10.100
10.110
10.111
SQL>selectcount(*)fromx$bhwhereobj=60026andstate=1;
COUNT(*)
----------
6
SQL>
如果有興趣可以看一下執行計劃在cache和no cache情況下物理讀的變化。