数据库管理-第339期 回看O记基础:物理读与逻辑读(20250619)

数据库管理-第339期 回看O记基础:物理读与逻辑读(20240619)

作者:胖头鱼的鱼缸(尹海文)
Oracle ACE Pro: Database
PostgreSQL ACE Partner
10年数据库行业经验
拥有OCM 11g/12c/19c、MySQL 8.0 OCP、Exadata、CDP等认证
墨天轮MVP,ITPUB认证专家
圈内拥有“总监”称号,非著 名社恐(社交恐怖分子)
公众号:胖头鱼的鱼缸
CSDN:胖头鱼的鱼缸(尹海文)
墨天轮:胖头鱼的鱼缸
ITPUB:yhw1809。
除授权转载并标明出处外,均为“非法”抄袭

3498ff20bcec87e9052f961f06737f3.png
最近半年做了给客户做了几次数据库的优化方案,本来以前是遇到性能问题发现了就提出建议并解决,现在搞得要汇总反馈。这期间由于客户新换的人真是对数据库一窍不通,加上友商在做类似事情的时候“做的太好”又着实把大家坑了一把。本期选了物理读和逻辑读这个方向,回顾一下Oracle数据库的基础知识。

1 基本概念

在Oracle数据库的AWR报表中,在SQL章节中,有下面两个分类:
image.png
image.png
简单来说就是按照从高速缓冲还是从磁盘读取数据的量来对SQL进行排序,前者就是我们一般说的逻辑读,后者则是物理读。从字面意思也很好理解,逻辑读就是直接从内存的buffer cache中获取需要的数据。同CPU的L1、L2、L3缓存类似,即需要的数据如果L1没有就去L2,再没有就去L3,L3没有就到内存,内存没有再到磁盘获取。如果buffer cache中没有需要的数据,就需要从磁盘中加载数据到内存中,这一操作就是物理读了。
在19c官方文档内存结构章节中,对对应的I/O操作也有解释:逻辑I/O,也称为Buffer I/O,是指buffer cache中buffer的读取和写入。当在内存中找不到请求的buffer时,数据库会执行物理I/O,将buffer从SSD或磁盘复制到内存中。然后,数据库执行逻辑I/O以读取缓存的buffer。
从概念来看,因为内存的I/O效率是远远高于磁盘的,因此逻辑读的效率肯定是远高于物理读的,因此当看到一个语句有非常多的逻辑读的时候,它不一定有问题!

2 数据库的buffer替换算法

cncpt217.gif
Buffer Cache是SGA的一部分,属于数据库实例结构中内存结构的一部分。相较于磁盘,内存虽然速度更快延迟更小,且是数量级的差距,但是内存也有容量小的问题,现在几十上百TB的数据库非常常见,但是往往单机内存还在512GB-1.5TB之间,因此内存中是不可能缓存整个数据库的数据的,即便想要堆机器实现,节点的交互效率也会极大拖慢数据库性能。
为了使Buffer访问高效,数据库必须决定在内存中缓存哪些buffer,以及从磁盘访问哪些buffer。在Oracle 19c中使用了两套主要的buffer替换算法:

  • 基于LRU的块级替换算法
    这个复杂的算法是默认的,它使用最近最少使用(LRU)列表,该列表包含指向脏缓冲区和非脏缓冲区的指针。LRU列表有热端和冷端。冷buffer是一种最近没有使用过的buffer。热buffer经常被访问,最近也被使用过。从概念上讲,只有一个LRU,但对于数据并发性,数据库实际上使用了多个LRU。在之前的文章《 数据库管理-第323期 Oracle如何统计表数据量(20250509)》也对LRU有过相对详细的介绍。
  • 基于热度的对象级替换算法
    从Oracle Database 12c Release 1(12.1.0.2)开始,自动大表缓存功能使表扫描能够在以下情况下使用不同的算法:
    – 并行查询
    在单实例和RAC数据库中,当DB_BIG_TABLE_CACHE_PERCENT_TARGET初始化参数设置为非零值,并且PARALLE_DEGREE_POLICY设置为自动或自适应时,并行查询可以使用大表缓存。
    – 串行查询
    仅在单实例配置中,当DB_BIG_TABLE_CACHE_PERCENT_TARGET初始化参数设置为非零值时,串行查询可以使用大表缓存。

当表未缓存在内存时,数据库会根据访问模式决定缓存哪些缓冲区。例如,如果一个常用的的表只有95%适合缓存至内存,那么数据库可能会选择将5%的块留在磁盘上,而不是循环地将块读入内存并将块写入磁盘,这种现象被称为抖动。当缓存多个大型对象时,数据库会将更常备使用的表视为更热的表,将不太被使用的表格视为更冷的表,这会影响缓存哪些块。DB_BIG_TABLE_CACHE_ERCENT_TARGET初始化参数设置使用此算法的缓冲区缓存的百分比。

就目前Oracle数据库的使用和维护经验来看,主要还是使用LRU

数据库已经有自己的算法来尽可能确保常用的数据都在内存中,因此我们要尽可能的避免人为的影响缓存机制逮住缓存数据受到影响,进而导致数据库性能下降。

3 充分利用内存

逻辑读虽然快,但是如果在内存里面还是以全表扫描的方式查询数据其实也是不合理的,因此在尽可能避免物理读的基础上我们还是要尽可能的减少逻辑读,和我们最常见的优化方法类似,索引既能提升查询效率,减少需要检索的buffer,也可以减少不必要的数据被缓存在内存中,从而提升内存的使用效率。
当然我们在生产中一定会遇到,当在一直使用常用数据的过程中突然要使用冷数据时,一定会出现的短时性能下降,这是不可避免但可以通过业务设计避免,用其他方式来使用冷数据从而高效利用内存提升热数据的性能。

总结

本期简单回顾了Oracle物理读与逻辑读,及一些相关的知识点。
老规矩,知道写了些啥。

请使用浏览器的分享功能分享到微信等