一、12c:官档
- Books → Performance Tuning Guide → Part III Tuning Database Memory → 13 Tuning the Database Buffer Cache
二、关于 Database Buffer Cache
对于许多类型的操作,Oracle数据库使用缓冲区缓存来存储从磁盘读取的数据块。Oracle数据库绕过缓冲区缓存,用于特定的操作,例如排序和并行读取。要有效地使用数据库缓冲区缓存,可以调优应用程序的SQL语句,以避免不必要的资源消耗。为了实现这一目标,验证经常执行的SQL语句和执行许多缓冲区的SQL语句都得到了良好的调优。
在使用并行查询时,考虑配置数据库以使用数据库缓冲区缓存,而不是直接读取程序全局区域(PGA)。当系统有大量内存时,这种配置可能是合适的。
See Also:
- 《Oracle Database SQL Tuning Guide》有关调优SQL语句的信息
- 《Oracle Database VLDB and Partitioning Guide》有关并行执行的信息
三、配置 Database Buffer Cache
在配置新的数据库实例时,不可能知道缓冲区缓存的正确大小。通常,数据库管理员对缓存大小进行第一次估计,然后在实例上运行一个有代表性的工作负载,并检查相关的统计数据,以查看缓存是否配置不足或配置过度。
本节描述如何配置数据库缓冲区缓存。如果您正在使用自动共享内存管理来配置共享全局区域(SGA),那么就不需要像本节描述的那样手动调优数据库缓冲区缓存。1 使用 V$DB_CACHE_ADVICE 视图
V$DB_CACHE_ADVICE 视图显示了一系列潜在缓冲区缓存大小的模拟缺失率。该视图通过提供预测每个潜在缓存大小的物理读取数量的信息来帮助缓存分级。数据还包括一个物理读取因子,这是一个因素,当缓冲区缓存被调整为给定值时,估计当前物理读取的数量会发生变化。然而,物理读取并不一定表示在Oracle数据库中读取磁盘,因为物理读取可以通过从文件系统缓存读取来完成。因此,成功地在缓存中找到的块和缓存的大小之间的关系并不总是一个平滑的分布。在调整缓冲池时,避免使用不为缓存命中率贡献(或贡献很小)的额外缓冲区。
下图演示了物理I/O比率和缓冲区缓存大小之间的关系。
- 随着缓冲区数目的增加,物理I/O比率降低。
- A和B点之间的物理I/O和点B和C的减少不平滑,如图中虚线所示。
- 从A点到B点增加缓冲的好处明显高于B点到C点。
- 随着缓冲区数目的增加,增加缓冲区的好处会减少。
使用 V$DB_CACHE_ADVICE 视图:
- 将DB_CACHE_ADVICE的初始化参数设置为ON。
这支持了咨询视图。DB_CACHE_ADVICE参数是动态的,因此可以动态地启用和禁用通知,以使您能够为特定的工作负载收集咨询数据。 - 在数据库实例上运行一个有代表性的工作负载。
在查询V$DB_CACHE_ADVICE视图之前,允许工作负载稳定。 - 查询V$DB_CACHE_ADVICE视图
下面的示例显示了这个视图的一个查询,该查询返回用于各种缓存大小的默认缓冲池的预测I/O需求。
COLUMN size_for_estimate FORMAT 999,999,999,999 heading 'Cache Size (MB)'
COLUMN buffers_for_estimate FORMAT 999,999,999 heading 'Buffers'
COLUMN estd_physical_read_factor FORMAT 999.90 heading 'Estd Phys|Read Factor'
COLUMN estd_physical_reads FORMAT 999,999,999 heading 'Estd Phys| Reads'
SELECT size_for_estimate, buffers_for_estimate, estd_physical_read_factor,
estd_physical_reads
FROM V$DB_CACHE_ADVICE
WHERE name = 'DEFAULT'
AND block_size = (SELECT value FROM V$PARAMETER WHERE name = 'db_block_size')
AND advice_status = 'ON';
该查询的输出可能如下所示:
Estd Phys Estd Phys
Cache Size (MB) Buffers Read Factor Reads
---------------- ------------ ----------- ------------
30 3,802 18.70 192,317,943 10% of Current Size
60 7,604 12.83 131,949,536
91 11,406 7.38 75,865,861
121 15,208 4.97 51,111,658
152 19,010 3.64 37,460,786
182 22,812 2.50 25,668,196
212 26,614 1.74 17,850,847
243 30,416 1.33 13,720,149
273 34,218 1.13 11,583,180
304 38,020 1.00 10,282,475 Current Size
334 41,822 .93 9,515,878
364 45,624 .87 8,909,026
395 49,426 .83 8,495,039
424 53,228 .79 8,116,496
456 57,030 .76 7,824,764
486 60,832 .74 7,563,180
517 64,634 .71 7,311,729
547 68,436 .69 7,104,280
577 72,238 .67 6,895,122
608 76,040 .66 6,739,731 200% of Current Size
在本例中,输出显示如果缓存为212 MB,而不是当前大小304 MB,那么物理读取的估计数将增加1.74,即74%。因此,不建议将缓存大小减小到212MB。
但是,将缓存大小增加到334MB可能会减少读取的因素。93年,或7%。如果系统上有额外的30MB内存,并且SGA_MAX_SIZE参数的值允许增量,建议将默认缓冲池大小增加到334MB。2 计算 Buffer Cache 缓存命中率
Buffer Cache 缓存命中率是计算在不需要磁盘访问的情况下,在缓冲区缓存中找到请求块的频率。这个比率是使用从V$SYSSTAT性能视图中选择的数据来计算的。使用缓冲区缓存命中率来验证V$DB_CACHE_ADVICE视图所预测的物理I/O。
表 1:列出了用于计算缓冲区缓存命中率的V$SYSSTAT视图的统计数据。表1:计算缓冲区缓存命中率的统计数据。
统计 | 描述 |
---|---|
consistent gets from cache | 从缓冲区缓存中请求一个块的一致性读取次数。 |
db block gets from cache | 从缓冲区缓存请求当前块的次数。 |
physical reads cache | 从磁盘读取到缓冲区缓存的数据块的总数。 |
SELECT name, value
FROM V$SYSSTAT
WHERE name IN ('db block gets from cache',
'consistent gets from cache',
'physical reads cache');
在本例中,通过使用直接从V$SYSSTAT视图中选择的值来简化查询,而不是通过一个间隔。建议在应用程序运行时,计算这些统计数据的delta值,然后使用这些delta值来确定缓冲区缓存命中率。有关在间隔中收集统计信息的信息,请参见“Automatic Performance Diagnostics ”。
使用该查询输出的值,使用以下公式计算缓冲区缓存的命中率:1 - (('physical reads cache') / ('consistent gets from cache' + 'db block gets from cache'))
See Also:
- 《Oracle Database Reference》有关V$SYSSTAT视图的信息。
3 解释 Buffer Cache 缓存命中率
在决定是否增加或减少缓冲区缓存大小之前,首先应该检查缓冲区缓存命中率。
低缓存命中率并不一定意味着增加缓冲缓存的大小将有利于性能。此外,高缓存命中率可能错误地表明缓冲区缓存的大小适合于工作负载。要解释缓冲区缓存命中率,请考虑以下因素:
- 避免重复扫描频繁访问的数据,通过在单个传递中执行处理或优化SQL语句。
重复扫描相同的大表或索引可以人为地提高低缓存命中率。检查经常执行的带有大量缓冲区的SQL语句,以确保这些SQL语句的执行计划是最优的。 - 通过在客户端程序或中间层缓存频繁访问的数据,避免使用相同的数据。
在运行OLTP应用程序的大型数据库中,许多行仅被访问一次(或从不访问)。因此,在内存中保持块的使用是没有目的的。 - 不要持续增加缓冲缓存大小。
如果数据库执行全表扫描或不使用缓冲区缓存的操作,缓冲区缓存大小的持续增加没有影响。 - 当出现大的全表扫描时,考虑糟糕的命中率。
在长时间全表扫描期间访问的数据库块放在最近使用的(LRU)列表的末尾,而不在列表的头部。因此,在执行索引查找或小表扫描时,块过期的速度比块读取速度快。
Note:
短表扫描是在特定大小阈值下对表进行扫描。小表格的定义是缓冲缓存的最大值为2%,或者是20,哪个更大。
4 增加分配给 Database Buffer Cache 的内存
如果缓存命中率低,并且您的应用程序被调优以避免执行全表扫描,请考虑增加缓冲区缓存的大小。如果可能,动态调整缓冲池,而不是关闭实例来执行此更改。
增加 Database Buffer Cache 的大小:- 将DB_CACHE_ADVICE的初始化参数设置为ON。
- 允许缓冲区缓存统计数据稳定。
- 检查V$DB_CACHE_ADVICE视图中的咨询数据,以确定需要显著减少物理I/O的数量的下一个增量,正如“Using the V$DB_CACHE_ADVICE View”所描述的那样。
- 如果可以将所需的额外内存分配给缓冲区缓存,而不导致系统进入页,那么就分配这个内存。
- 要增加分配给缓冲区缓存的内存数量,请增加DB_CACHE_SIZE初始化参数的值。
DB_CACHE_SIZE参数指定数据库标准块大小的默认缓存大小。要创建和使用除数据库标准块大小以外的块大小的表空间(例如用于传输表空间的表空间),为每个块大小配置一个单独的缓存。使用DB_nK_CACHE_SIZE参数配置所需的非标准块大小(其中n为2、4、8、16或32,而不是标准块大小)。
Note:
- 选择缓存大小的过程是相同的,不管缓存是默认的标准块大小缓存、保留或循环缓存,还是非标准块大小缓存。
- 当缓存被显著调整(大于20%)时,旧的缓存咨询值就会被丢弃,缓存建议将被设置为新的大小。否则,旧的缓存咨询值将根据现有值的插值调整到新的大小。
更多关于 DB_nK_CACHE_SIZE 参数的信息,请看:
- 《Oracle Database Administrator's Guide》
- 《Oracle Database Reference》
5 减少分配给 Database Buffer Cache 的内存
如果缓存命中率很高,那么缓冲缓存可能足够大,可以存储最频繁访问的数据。如果这是另一个内存结构需要的情况和内存,考虑减小缓冲区缓存的大小。
减少 Database Buffer Cache 的大小:- 检查V$DB_CACHE_ADVICE视图中的咨询数据,以确定减小缓冲区缓存的大小是否会显著增加物理I/Os的数量,正如“Using the V$DB_CACHE_ADVICE View”所描述的那样。
- 为了减少分配给缓冲区缓存的内存数量,减少DB_CACHE_SIZE初始化参数的值。
四、配置多个缓冲池
对于大多数系统,单个默认缓冲池通常是足够的。但是,对应用程序的缓冲池有详细了解的数据库管理员可以从配置多个缓冲池中获益。
对于具有非典型访问模式的段,可以考虑将这些段存储在两个单独的缓冲池中:KEEP 池和 RECYCLE 池。一个段的访问模式可能是非典型的,如果它经常被访问(有时被称为热)或不经常访问(比如一个大的段,每天只被一个批处理工作访问一次)。使用多个缓冲池可使您处理这些异常情况。您可以使用KEEP池来维护缓冲区缓存中经常被访问的段,RECYCLE池是为防止对象在缓冲区缓存中消耗不必要的空间。当对象与缓冲区缓存相关联时,所有来自该对象的块都放置在该缓存中。Oracle数据库为未分配到特定缓冲池的对象维护一个DEFAULT 缓冲池。默认缓冲池大小由DB_CACHE_SIZE初始化参数决定。每个缓冲池使用相同的LRU替换策略。例如,如果 KEEP 池不够大,不能存储分配给它的所有段,那么最老的块就会超出缓存。
通过将对象分配到适当的缓冲池,您可以:
- 减少或消除 I/O
- 将对象隔离或限制到单独的缓存。
1 考虑使用多个缓冲池
1.1 随机存取大段
当一个非常大的段(与缓冲区缓存的大小相比较)使用一个大的或无界的索引范围扫描访问时,一个LRU老化方法可能会出现问题。任何单个部分(超过10%)的非连续物理读取都可以被认为是非常大的。对大段的随机读取可能会导致包含其他段数据的缓冲区从缓存中过期。大型段最终消耗了大量缓冲区缓存,但它不会从缓存中获益。
经常被访问的段不受大段读取的影响,因为它们的缓冲区被频繁地加热,它们不会从缓冲区缓存中消失。然而,这个问题会影响到不经常被访问的热段,从而在大型段读取的缓冲区老化过程中存活下来。解决这个问题有三种选择:- 如果访问的对象是一个索引,则确定该索引是否具有选择性。如果没有,请调优SQL语句以使用更有选择性的索引。
- 如果对SQL语句进行了调优,则将大段移动到一个单独的 RECYCLE 缓存中,这样就不会影响到其他部分。RECYCLE 缓存应该比DEFAULT 缓冲池小,并且应该更快地重用缓冲区。
- 或者,考虑将小的、温暖的段移到一个单独的KEEP 缓存中,而不是用于大的段。KEEP 缓存的大小,用以最小化缓存中的遗漏。您可以通过存储在KEEP 缓存中的查询访问的段来保证它们不过时,从而使特定查询的响应时间更可预测。
1.2 Oracle RAC 实例
在Oracle Real Application Cluster (Oracle RAC)环境中,考虑为每个数据库实例创建多个缓冲池。不需要为数据库的每个实例定义相同的缓冲池集。在实例中,缓冲池可以是不同大小或未定义的。根据该实例的应用程序需求调整每个实例。
2 使用多个Buffer Pools
若要为对象定义默认缓冲池,请使用存储子句的BUFFER_POOL关键字。此子句对以下SQL语句有效:- CREATE TABLE
- CREATE CLUSTER
- CREATE INDEX
- ALTER TABLE
- ALTER CLUSTER
- ALTER INDEX
当使用ALTER语句更改对象的缓冲池时,当前包含被修改段块的所有缓冲区都位于它们在ALTER语句之前的缓冲池中。新加载的块和已加载的任何块,并将其重新加载到新的缓冲池中。
See Also:
- 《Oracle Database SQL Language Reference》有关在存储子句中指定BUFFER_POOL的信息。
3 使用V$DB_CACHE_ADVICE视图用于单独的缓冲池
与默认缓冲池一样,您可以使用V$DB_CACHE_ADVICE视图来帮助缓存其他池的大小。在估计初始缓存大小并运行一个具有代表性的工作负载后,查询您想要使用的池的v$ DB_CACHE_ADVICE视图。
有关使用V$DB_CACHE_ADVICE视图的更多信息,请参见“Using the V$DB_CACHE_ADVICE View”。示例 2 显示了这个视图的查询,查询来自 KEEP 池的数据:
示例 2:查询保存池的V$DB_CACHE_ADVICE视图
SELECT size_for_estimate, buffers_for_estimate, estd_physical_read_factor,
estd_physical_reads
FROM V$DB_CACHE_ADVICE
WHERE name = 'KEEP'
AND block_size = (SELECT value FROM V$PARAMETER WHERE name = 'db_block_size')
AND advice_status = 'ON';
4 计算单个缓冲池的缓冲池命中率
V$SYSSTAT 视图中的数据反映了一组统计数据中所有缓冲池的逻辑和物理读数。要单独确定缓冲池的命中率,请查询V$BUFFER_POOL_STATISTICS视图。这个视图维护对每个池的逻辑读和写的数量的统计。
See Also:- 《Calculating the Buffer Cache Hit Ratio》有关计算命中率的更多信息。
- 《Oracle Database Reference》有关V$BUFFER_POOL_STATISTICS视图的更多信息。
示例 3:查询V$BUFFER_POOL_STATISTICS视图
SELECT name, physical_reads, db_block_gets, consistent_gets,
1 - (physical_reads / (db_block_gets + consistent_gets)) "Hit Ratio"
FROM V$BUFFER_POOL_STATISTICS;
5 检查缓冲区缓存使用模式
V$BH视图显示当前驻留在SGA中的所有块的数据对象ID。要确定池中哪些段有多个缓冲区,请使用此视图检查缓冲区缓存使用模式。您可以查看所有段或特定段的缓冲区缓存使用模式,如下面的部分所述:5.1 检查所有区段的缓冲区缓存使用模式
确定池中有多个缓冲区的一种方法是查询在给定时间内驻留在缓冲区缓存中的所有段的块数。根据缓冲区缓存大小,这可能需要大量的排序空间。示例 4:显示了一个查询,该查询计算所有段的块数。
示例 4 查询所有段的块数
COLUMN object_name FORMAT A40
COLUMN number_of_blocks FORMAT 999,999,999,999
SELECT o.object_name, COUNT(*) number_of_blocks
FROM DBA_OBJECTS o, V$BH bh
WHERE o.data_object_id = bh.OBJD
AND o.owner != 'SYS'
GROUP BY o.object_Name
ORDER BY COUNT(*);
该查询的输出可能如下所示:
OBJECT_NAME NUMBER_OF_BLOCKS
---------------------------------------- ----------------
OA_PREF_UNIQ_KEY 1
SYS_C002651 1
..
DS_PERSON 78
OM_EXT_HEADER 701
OM_SHELL 1,765
OM_HEADER 5,826
OM_INSTANCE 12,644
5.2 检查特定段的缓冲区缓存使用模式
另一种确定在池中有多个缓冲区的方法是计算单个对象在给定时间使用的缓冲区缓存的百分比。计算单个对象使用的缓冲区缓存的百分比:
- 通过查询DBA_OBJECTS视图,找到该段的Oracle数据库内部对象号:
因为两个对象可以具有相同的名称(如果它们是不同类型的对象),则使用OBJECT_TYPE列来标识感兴趣的对象。SELECT data_object_id, object_type FROM DBA_OBJECTS WHERE object_name = UPPER('segment_name');
- 为SEGMENT_NAME查找缓冲区缓存中的缓冲区数目:
对于data_object_id_value,从上一步使用DATA_OBJECT_ID的值。SELECT COUNT(*) buffers FROM V$BH WHERE objd = data_object_id_value;
- 在数据库实例中找到缓冲区的数量:
SELECT name, block_size, SUM(buffers) FROM V$BUFFER_POOL GROUP BY name, block_size HAVING SUM(buffers) > 0;
- 计算缓冲区到总缓冲区的比率,以获得当前SEGMENT_NAME所使用的缓存的百分比:
% cache used by segment_name = [buffers(Step2)/total buffers(Step3)]
此方法仅适用于单个段。对于一个分区对象,运行每个分区的查询。
6 配置 KEEP 池
KEEP 缓冲池的目的是在内存中保留对象,从而避免I/O操作。在内存中保存的每个对象都会导致一种交换。在缓存中保持频繁访问的块更有益。避免在缓存中保留不经常使用的块,因为这会减少其他更活跃的块的空间。如果您的应用程序中有一些经常被引用的片段,那么考虑将这些块存储在 KEEP 缓冲池中的那些段中。保存在 KEEP 池中的典型段是小的、经常使用的引用表。要确定哪些表是候选表,可以通过查询V$BH视图(如“Examining the Buffer Cache Usage Pattern”中所描述的),从候选表中检查块的数量。
配置 KEEP 池:
- 计算 KEEP 缓冲池的近似大小。
KEEP 缓冲池的大小取决于要保存在缓冲区缓存中的对象。要估计其大小,请添加分配给该池的所有对象使用的块。
如果您收集了段的统计信息,请查询DBA_TABLES.BLOCKS 和DBA_TABLES.EMPTY_BLOCKS确定所使用的块的数量。 - 在不同的时间拍摄两个系统性能的快照。
使用V$DB_CACHE_ADVICE视图从 KEEP 池中获取每个快照的查询数据,如“Using the V$DB_CACHE_ADVICE View for Individual Buffer Pools”所描述的那样。 - 减去物理读、块获取、一致性获取的最近值,并使用结果来计算命中率。
缓冲池命中率100%可能不是最优的。通常,您可以减少 KEEP 缓冲池的大小,并且仍然保持足够高的命中率。将从 KEEP 缓冲池中删除的块分配给其他缓冲池。 - 通过将DB_KEEP_CACHE_SIZE参数的值设置为所需的大小,将内存分配给保持缓冲池。
保留池的内存不是默认池的子集。
Note:
如果一个对象在大小上增长,那么它可能不再适合于 KEEP 缓冲池。您将开始从缓存中丢失块。7 配置 RECYCLE 池
您可以配置一个 RECYCLE 缓冲池,用于那些您不想保存在内存中的块。RECYCLE 池的目的是保留被扫描很少或不经常被引用的片段。如果一个应用程序随机访问一个非常大的对象的块,那么它就不太可能被存储在缓冲池中,以便在它过时之前被重用。不管缓冲池的大小(考虑到可用物理内存的数量),这都是正确的。因此,对象的块不需要缓存;缓存缓冲区可以分配给其他对象。不要过快地丢弃内存块。如果缓冲池太小,那么在事务或SQL语句完成其执行之前,块可以从缓存中退出。例如,应用程序可以从表中选择一个值,使用该值处理一些数据,然后更新记录。如果在SELECT语句之后从缓存中删除该块,则必须再次从磁盘读取该块以执行更新。在用户事务期间,应该保留该块。
配置 RECYCLE 池:
- 通过将DB_RECYCLE_CACHE_SIZE参数的值设置为所需的大小,将内存分配给循环缓冲池。
RECYCLE 池的内存不是默认池的子集。
五、配置 Redo Log Buffer
服务器进程对缓冲区缓存中的数据块进行更改会生成重做数据到日志缓冲区中。日志写入器进程(LGWR)开始从重做日志缓冲区的复制条目写入到在线重做日志,如果发生以下条件:
- redo log buffer 至少已满三分之一。
- LGWR是由服务器进程执行 COMMIT 或 ROLLBACK 语句时发布的。
- 一个数据库写入器进程(DBWR)发布LGWR。
在拥有快速处理器和相对较慢的磁盘的系统上,处理器可能会在重做日志写入器将重做日志缓冲区的一部分移动到磁盘的时候填充重做日志缓冲区的其余部分。在这种情况下,一个较大的重做日志缓冲区可以暂时屏蔽慢磁盘的影响。或者,要么考虑改善:
- 检查点或归档进程。
- 通过将所有在线日志移动到快速原始设备,达到调优LGWR性能的目的。
- 批处理提交操作用于批处理作业,以便LGWR能够有效地编写重做日志条目。
- 在加载大量数据时使用NOLOGGING操作。
1 调整 Redo Log Buffer 大小
重做日志缓冲区的默认大小如下所示:
MAX(0.5M, (128K * number of cpus))
插入、修改或删除大量数据的应用程序可能需要更改重做日志缓冲区的默认大小。Oracle建议将重做日志缓冲区大小设置为最小为8 MB,使用flashback功能将其设置为至少64 MB,并拥有4GB或更高的SGA。如果您使用的是具有异步重做传输的Oracle数据保护,并且具有较高的重做生成率,则将其设置为至少256 MB。
要确定重做日志缓冲区的大小是否太小,请监视重做日志缓冲区统计信息,如“Using Redo Log Buffer Statistics”所描述的那样。还可以检查日志缓冲区空间等待事件是否是数据库实例等待时间的重要因素。如果不是,那么日志缓冲区的大小很可能是适当大小的。See Also:
- 《Oracle Database High Availability Best Practices》
- 通过将LOG_BUFFER初始化参数的值设置为所需的大小,设置重做日志缓冲区的大小。
该参数的值以字节表示。
Note:
在实例启动后不能修改重做日志缓冲区的大小。
2 使用 Redo Log Buffer 统计
REDO BUFFER ALLOCATION RETRIES 统计数据反映了用户进程在 REDO 日志缓冲区中等待空间的次数。可以使用V$SYSSTAT性能视图查询此统计数据。在应用程序运行期间,您应该监视 redo buffer allocation retries 统计数据。这个统计数据的值应该在一个区间上接近于零。如果此值持续增加,则意味着用户进程必须等待 redo log buffer 中的空间可用。等待可以由 redo log buffer 太小或通过检查点引起。在这种情况下,考虑以下选项之一:
- 增加重做日志缓冲区的大小,如“Sizing the Redo Log Buffer”所述
- 改善检查点或归档进程。
示例 5:查询 V$SYSSTAT 视图
SELECT name, value
FROM V$SYSSTAT
WHERE name = 'redo buffer allocation retries';
六、配置数据库缓存模式
从Oracle Database 12c Release 1(12.1.0.2)开始,有两种数据库缓存模式:以前版本的Oracle数据库中使用的默认数据库缓存模式,以及强制完整的数据库缓存模式。在默认的缓存模式下,Oracle数据库并不总是在用户查询大表时缓存底层数据。在强制完整的数据库缓存模式中,Oracle数据库假定缓冲区缓存足够大,可以缓存完整的数据库,并试图缓存查询访问的所有块。
Note:从Oracle数据库12c Release 1(12.1.0.2)开始,可以使用Force full数据库缓存模式。
1 默认数据库缓存模式
默认情况下,Oracle数据库在执行全表扫描时使用默认的数据库缓存模式。在默认的缓存模式下,当用户查询一个大表时,Oracle数据库并不总是缓存底层数据,因为这样做可能会从缓冲区缓存中删除更多有用的数据。
如果Oracle数据库实例确定有足够的空间来缓存缓冲区缓存中的完整数据库,并且这样做是有益的,那么实例将自动缓存缓冲区缓存中的完整数据库。如果Oracle数据库实例确定没有足够的空间来缓存缓冲区缓存中的完整数据库,那么:
- 只有当表大小小于缓冲区缓存大小的2%时,较小的表才被加载到内存中。
- 对于中表,Oracle数据库分析了最后一个表扫描和缓冲区缓存的老化时间戳之间的间隔。如果在最后一个表扫描中重用的表的大小大于剩余的缓冲区缓存大小,则缓存表。
- 大型表通常不会加载到内存中,除非您显式地声明了保存缓冲池的表。
在默认的缓存模式下,Oracle数据库实例不缓存缓冲缓存中的NOCACHE lob。
See Also:
- 《Oracle Database Concepts》有关默认数据库缓存模式的信息
2 强制完整的数据库缓存模式
随着更多的内存被添加到数据库中,缓冲区缓存大小可能会持续增长。在某些情况下,缓冲区缓存的大小可能会变得非常大,以至于整个数据库都可以放入内存中。当执行全表扫描或访问lob时,在内存中缓存整个数据库的能力可以极大地提高数据库性能。
在强制完全数据库缓存模式下,当数据库的大小小于数据库缓冲区缓存大小时,Oracle数据库会在内存中缓存整个数据库。所有数据文件(包括使用SecureFiles的NOCACHE lob和lob)都被加载到缓冲区缓存中,因为它们正在被访问。See Also:
- 《Oracle Database Concepts》
- 《Oracle Database Administrator's Guide》
3 确定何时使用强制完整数据库缓存模式
为了提高表扫描和LOB数据访问的数据库性能,特别是对于受I/O吞吐量或响应时间限制的工作负载,当数据库缓冲区缓存的大小大于数据库的大小时,考虑使用force full数据库缓存模式。考虑在以下情况下使用强制完全数据库缓存模式:
- 在Oracle RAC环境中,逻辑数据库大小(或实际使用的空间)小于每个数据库实例的单独缓冲区缓存。这也适用于非oracle RAC数据库。
- 在Oracle RAC环境中,逻辑数据库的大小小于所有数据库实例的总缓冲区缓存大小(例如,通过实例访问)的80%。
- 数据库使用SGA_TARGET或MEMORY_TARGET。
- 需要缓存NOCACHE lob。除非使用强制完整的数据库缓存,否则不会缓存NOCACHE lob。
当一个Oracle RAC数据库实例使用force full数据库缓存模式时,Oracle RAC环境中的所有其他数据库实例也将使用force full数据库缓存模式。
在多租户环境中,强制完整的数据库缓存模式适用于整个容器数据库(CDB),包括其所有可插入数据库(PDBs)。
4 验证数据库缓存模式
默认情况下,Oracle数据库在默认的数据库缓存模式下运行。验证是否启用了完整的数据库缓存模式:
- 查询V$DATABASE视图如下:
如果查询返回YES的值,则在数据库上启用完整的数据库缓存模式。如果查询返回NO的值,则禁用完整的数据库缓存模式,数据库处于默认的数据库缓存模式。SELECT FORCE_FULL_DB_CACHING FROM V$DATABASE;
Note:
要启用完整的数据库缓存模式,请使用以下ALTER database命令:
ALTER DATABASE FORCE FULL DATABASE CACHING;
- 《Oracle Database Administrator's Guide》了解有关启用和禁用强制完整数据库缓存模式的更多信息
- 《Oracle Database Reference》了解有关 V$DATABASE 视图的更多信息