} 重温下 databuffer 这里没有解决问题,databuffer倒是清楚了不少 什么条件下走物理读待解。
Data Buffer是什么
Data Buffer是oracle的数据缓存。位于SGA中。当Oracle从硬盘上读取了一段应用数据后,会把这段数据存在Data Buffer中。因为Oracle认为如果一个数据被使用过,那么下次使用它的可能性会很大,所以放在缓存中,下次就可以直接从缓存中提取,不必去从硬盘中提取,因为计算机对内存的访问速度远远高于硬盘。Oracle在读取一个数据的时候默认的顺序也是先查找Data Buffer,如果找不到才去硬盘中查找。这个过程中,如果找到了就叫buffer cache hit 。 Oracle术语中DCHR就是指 buffer cache hit ratio。 这个值越高,说明相对的性能越好。
Data Buffer的种类
初学者可能认为数据库中只有一个 Data Buffer,但其实不是这样的。 oracle中至少应该有7种data buffer。这从下面的命令可以看出来
点击(此处)折叠或打开
SQL> show parameter cache
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_16k_cache_size big integer 0
db_2k_cache_size big integer 0
db_32k_cache_size big integer 0
db_4k_cache_size big integer 0
db_8k_cache_size big integer 0
db_cache_advice string ON
db_cache_size big integer 0
db_keep_cache_size big integer 0
db_recycle_cache_size big integer 0
object_cache_max_size_percent integer 10
object_cache_optimal_size integer 102400
session_cached_cursors integer 20
其中db_nk_cache_size这一部分,n的值有2,4,8,16,32 一共5种,对应的也就应该有5种data buffer。同时db_cache_size, db_keep_cache_size, db_recycle_cache_size这里又有3个data buffer。但是其实 db_cache_size所对应的data buffer和 前面提到的5个nk buffer中的某一个data buffer是同一个。所以我们一共有7种 data buffer。不过对于大多数oracle 数据库,虽然可以存在7种 data buffer,但通常情况下只会设置一个 data buffer. 下面可以一一观察一下这几种data buffer。
db_nk_cache_size
在Oracle中,可以存在五种不同的 数据块尺寸。这些尺寸是2K,4K,8K,16K,32K。 其中,system表空间所使用的数据块尺寸叫做标准块尺寸。由参数 db_block_size指定。对于非system的表空间,在创建表空间的时候可以指定非标准的数据块尺寸。当oracle读取数据的时候,如果读取的block所在的表空间的块尺寸为32K,那么这个数据读取之后就只能放到db_32k_cache_size这个参数对应的 data buffer中去。无法放到别的中。 所以如果你创建了一个block 为nk大小的表空间,那么你就一定要设置 db_nk_cache_size这个data buffer。
db_cache_size
我们知道Oracle可以存在不同的块尺寸,但其中有一个默认的标准块尺寸,也就是system使用的块尺寸,由db_block_size指定。那么这里的db_cache_size就制定了默认的块尺寸的data buffer的大小。也就是说,它跟前面的 nk中的标准块尺寸缓存是同一个。 不过要注意的是,这两个参数只可以设置一个。
db_keep_cache_size
这个参数对应的data buffer的性质是,如果一个数据对象load进了该缓存,就不会被交换出去了。 某些时候我们希望一些数据对象永久驻在缓存中,就可以采用这个data buffer。
db_recycle_cache_size
该缓存中的数据被使用完会立即清除
Data Buffer 中的数据块访问
这里主要指默认块大小的data buffer。data buffer中有两个链表,一个是写链表,一个是空闲链表。写链表上的buffer是将要被写入数据文件的,而空闲链表则记录着可用的Data Buffer。 空闲链表采用LRU管理。Oracle访问过一个数据块后会把他放在空闲链表的MRU端,当需要从硬盘读数据进入data buffer的时候,则从LRU端分配内存。但是有一个特例要注意,就是全表扫描。
全表扫描时的data buffer
在全表扫描的时候,oracle默认认为这些读入的数据不会再次被使用了,所以就把这些数据块放到空闲链表的LRU端。但有的时候,其实我们希望这些数据被再次使用,那么就希望把这些数据放在MRU端,这样你需要在创建表的时候指定cache参数。
一些相关的参数和视图
db_cache_advice v$db_cache_advice
db_cache_advice有两个值,on和 off。 当为true的时候,oracle会根据运行的统计信息等为data buffer的大小做出一些调整建议,建议信息就在 v$db_cache_advice中。
该视图的列说明:
id
data buffer的ID 1-8。 其中7是db_keep_cache_size 8是db_recycle_cache_size
name
data buffer的名称
BLOCK_SIZE
缓冲池 block size (字节为单位)
ADVICE_STATUS
建议器的状态,也就是db_cache_advice的状态。on为打开,off为关闭。如果关闭,则数据是上次的
SIZE_FOR_ESTIMATE
假设的(预测)cache大小(M 为单位)
ESTD_PHYSICAL_READ_FACTOR
当cache为SIZE_FOR_ESTIMATE所估算的大小时,物理读的次数与当前物理读的比率
在使用这个视图的时候重点关注ESTD_PHYSICAL_READ_FACTOR 这一项。 随着SIZE_FOR_ESTIMATE的不断增大,这个值会不断变化,代表着物理读越来越小。
我们要找的是哪个变化不再明显的点。这时候就意味着 data buffer已经足够大了,已经不在是一个影响物理读的决定因素了。
v$buffer_pool
该视图记录了数据库中所有 data buffer的详细信息。字段
数据类型
描述
ID
NUMBER
缓冲池ID,和上面视图描述相同。
NAME
VARCHAR2(20)
缓冲池名称
BLOCK_SIZE
NUMBER
缓冲池块尺寸(字节为单位)
RESIZE_STATE
VARCHAR2(10)
缓冲池当前状态。
STATIC:没有被正在调整大小
ALLOCATING:正在分配内存给缓冲池(不能被用户取消)
ACTIVATING:正在创建新的缓存块(不能被用户取消)
SHRINKING:正在删除缓存块(能被用户取消)
CURRENT_SIZE
NUMBER
缓冲池大小(M为单位)
BUFFERS
NUMBER
当前缓存块数
TARGET_SIZE
NUMBER
如果正在调整缓冲池大小(即状态不为STATIC),这记录了调整后的大小(M为单位)。如果状态为STATIC,这个值和当前大小值相同。
TARGET_BUFFERS
NUMBER
如果正在调整缓冲池大小(即状态不为STATIC),这记录了调整后的缓存块数。否则,这个值和当前缓存块数相同。
PREV_SIZE
NUMBER
前一次调整的缓冲池大小。如果从来没有调整过,则为0。
PREV_BUFFERS
NUMBER
前一次调整的缓存块数。如果从来没有调整过,则为0。
v$buffer_pool_statistics
该视图记录了各个data buffer的统计信息,于上面视图的不同就是该视图主要会包含一些 read次数等信息,而上一个视图主要是 data buffer的大小。
v$bh
该视图记录了数据对象在data buffer中的信息,精细到数据块级别.