平均提速20倍!Oracle 12c In-Memory最佳实践

Posted DBAplus社群

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了平均提速20倍!Oracle 12c In-Memory最佳实践相关的知识,希望对你有一定的参考价值。



来源:三墩IT人 订阅号

            马力行(新炬网络数据库工程师)


一、IM特性简介


Oracle 12.1.0.2 引入了In-Memory Column Store(以下简称IM)新特性,该特性开启后会在数据库启动阶段在SGA中分配一块静态的内存池In-Memory Area,用于存放以列式存储的用户表。


列式存储的优点是在访问数据时只需要访问数据的部分列,而不像行式存储,需要访问数据的所有列。列式存储可以避免大量不必要I/O,且每一列的列值即为索引,可以显著提高查询性能。


IM列式存储并不会替换传统的buffer cache行式存储,而是作为补充,Oracle优化器会根据两种方式的特点自行选择适合的方式来取数据。


下图展示Oracle以两种方式存储数据:


平均提速20倍!Oracle 12c In-Memory最佳实践


IM可以对存入的表进行压缩,压缩级由低到高分别为:


  1. NO MEMCOMPRESS  

  2. MEMCOMPRESS FOR DML

  3. MEMCOMPRESS FOR QUERY LOW 

  4. MEMCOMPRESS FOR QUERY HIGH

  5. MEMCOMPRESS FOR CAPACIT LOW

  6. MEMCOMPRESS FOR CAPACITY HIGH


默认级别为MEMCOMPRESS FOR QUERY LOW,该级别在有效压缩表的同时提供最佳的查询性能,数据库不对数据进行解压读取,而是采用数据字典压缩方式,即删除重复数据来减少内存使用。此外,其它更高的级别的压缩方式需要对数据进行压缩,会增加额外消耗。


二、IM特性测试


1.开启IM特性


IM特性由inmemory_size 参数控制,只要参数值大于0,该特性即被开启,注意,inmemory_size 至少设置100M,否则无法启动实例,报错ORA-64353:


平均提速20倍!Oracle 12c In-Memory最佳实践


以设置inmemory_size=10g 为例:

Alter system set inmemory_size=10g sid=‘db12c1’ scope=spfile;


重启实例后,SGA分配时会多出一项IN-Memory Area,说明IM特性已被打开。


平均提速20倍!Oracle 12c In-Memory最佳实践


2.IM性能测试


>>>>

全表扫描


以一张36万行的表进行全表扫描为例:


未开启IM:


平均提速20倍!Oracle 12c In-Memory最佳实践


开启IM后:


平均提速20倍!Oracle 12c In-Memory最佳实践


可以看到,开启IM后TABLE ACCESS FULL变为TABLE ACCESS INMEMORY FULL,逻辑读从6130降为6,CPU cost由427降为17,性能有成百上千倍的提升。


>>>>

表连接查询


im_tab_ja表有10万条记录,im_tab_jb表有2000多条记录,两表做关联查询测试。


未开启IM特性:


平均提速20倍!Oracle 12c In-Memory最佳实践


开启IM特性:


平均提速20倍!Oracle 12c In-Memory最佳实践


可以看到,IM对表关联查询的提升也非常明显。


>>>>

行式存储更优的情况


im_tab_ja有10万条数据,在im_tab_ja表的table_name列加索引,数据离散度很高,对应的索引选择性也就较好,此时进行全字段查询,过滤字段为table_name。


IM 特性开启后默认情况下执行计划并没有走IM的扫描:


平均提速20倍!Oracle 12c In-Memory最佳实践


指定执行计划走IM:


平均提速20倍!Oracle 12c In-Memory最佳实践


虽然强制执行计划走了IM,但是逻辑读是59,远高于默认的走索引+行式存储的执行计划,可见在数据离散度较高,且通过索引条件过滤的扫描场景中,IM特性对性能并没有提升,传统的索引+行式存储的执行计划已经足够,在默认情况下还是会根据查询索引返回rowid的方式查找数据。


3.IM压缩比测试


> >>>

重复值对压缩比的影响


由于IM压缩是基于重复数据删除的压缩, 对300000条数据但不同数据只有两条的im_gender表和同样有300000条数据但每条数据都不重复的im_table表进行压缩测试。


平均提速20倍!Oracle 12c In-Memory最佳实践


im_gender 表压缩比达3.56,而im_phone的压缩比只有0.98,反而增大了。由此可知,重复值高有助于提高压缩比,而几乎无重复值的表压缩效果就很差。


>>>>

压缩模式不同对压缩比的影响


为了方便操作和对比,这里调用了DBMS_COMPRESSION.GET_COMPRESSION_RATIO对压缩比进行预估:


平均提速20倍!Oracle 12c In-Memory最佳实践


可见,压缩比随着压缩等级的提升而提升,这里选择被压缩的表是根据dba_objects create as出来的,数据分布有一定的代表性,但在实际操作中,压缩效果要根据具体情况具体分析。


三、IM生产实践


目前,浙江移动X系统已经启用了IM特性,在启用特性之前,业务反馈查询缓慢,业务页面将超时设置由30s调整至60s的情况下,仍然频繁出现页面超时问题,业务高峰期的超时概率高达60%。经过深度分析发现业务SQL本身并无有效的过滤条件,最终只能定位到分区全扫查询,也就是无法单纯从优化SQL的方式上进行解决。同时数据库资源池上本身存在较多的pdb,大量的全表扫描消耗较多的IO资源,对其他的pdb也造成影响。


由于SQL承载的是分析类业务,通过分析该类表的统计信息发现数据离散度较低,比较符合IM的适用场景。在进行为期3周的严格测试和运维场景模拟实验后,最终通过变更完成Oracle12C的IM特性在生产中的首次应用。


优化效果:查询效率由几十秒至数分钟不等的查询时间,降低至200ms完成目标数据的扫描。目前使用1个月以上,应用反馈页面响应速度良好,页面最终的响应速度在3s左右,平均提速20倍以上,业务成功率高达100%。


相关SQL的执行计划前后对比:


启用IM前:


平均提速20倍!Oracle 12c In-Memory最佳实践


启用IM后:


平均提速20倍!Oracle 12c In-Memory最佳实践


物理读由168357多降为0,逻辑由168493降为24,cpu cost由29840降为2741,执行时间由6.65s降为0.23s, 效果显著。


压缩比情况:


平均提速20倍!Oracle 12c In-Memory最佳实践


压缩比在默认压缩级别下已经达到了5-12倍的压缩比例。


综合上述表现,IM特性在适用的场景下对性能的提升是非常明显的,在消耗相对少量额外内存的条件下实现了巨大的性能提升。


四、IM日常维护


IM特性是需要不定期维护的,不仅需要关注IM中表是否加载成功,是否出现In-Memory Area不足的情况,在内存资源有限的情况下,还要优化IM中存放的表,及时添加需要的表,删除不需要的表。此外,还可以添加或删除IM表中的部分字段或分区,达到优化内存使用的目的。


1.IM添加和删除表


  • 当IM特性开启后,往in memory列式存储中加表,命令如下:Alter table tab_name inmemory;

    注意,当执行以上命令时,Oracle并不会将表马上存入in memory中,而是需要通过一次查询操作触发。

    删除表的操作为:Alter table tab_name no inmemory;


  • 假如一张表有许多字段,但查询的时候只用到其中的某些字段,那么,就可以只存储相关字段:Alter table im_table inmemory no inmemory(object_name);  --除去表的object_name字段


  • 假如一张表有多个分区,可以除去其中的某些分区:Alter table im_table modify partition P_201601 no inmemory;  --除去表的P_201601分区


2.维护常用视图


>>>>

v$inmemory_area


该视图用来查看In-Memory Area内存区域的使用情况:


平均提速20倍!Oracle 12c In-Memory最佳实践


In-Memory Area 分两个子池,1MB POOL 用来存放列式数据,64KB POOL用来存放元数据和事务信息。POPULATE_STATUS表明当前子池加载状态,DONE表示所有数据已经加载完毕,POPULATING表示正在加载,而OUT OF MEMORY表示分配的空间不足,需要删表或增大In-Memory Area。


>>>>

v$im_segments


该视图用来查看IM中存放段的情况:


平均提速20倍!Oracle 12c In-Memory最佳实践


可以用来查看inmemory中添加了多少表,占用多大内存空间等。


>>>>

v$im_column_level


该试图用来查看IM中存放的字段情况:




可以看到object_name字段的inmemory_compression 显示为no inmemory,表明该字段并未加入IM。


3.其他注意事项


由于inmemory特性的开启是以实例为单位的,在RAC环境中,可以在不同的节点设置不同的inmemory_size, 加载不同的表,以适应不同节点访问不同数据的业务分配机制。


Inmemory_size参数可以在线修改,但是必须重启实例后才能生效,所以在启用初期就应该规划好,避免设置后出现内存不足、无法加表的情况。


Inmemory area是SGA中的一个静态子池,占用SGA,所以在加inmemory_size 的时候应该相应调大SGA,以免挤掉其他子池的空间。


精选专题(官网:dbaplus.cn)

◆  近期热文  ◆  


◆  MVP专栏  ◆  

丨丨丨

以上是关于平均提速20倍!Oracle 12c In-Memory最佳实践的主要内容,如果未能解决你的问题,请参考以下文章

超详细Centos7 安装 Oracle 12c

ChatGPT付费就变快!实测提速超2倍正确率更高,定价每月20刀

如何让 Xcode 在读写上提速100倍?

如何用Apache Kylin让Hive表查询提速千百倍

用 Taichi 加速 Python:提速 100+ 倍!

如何让 Xcode 在读写上提速100倍?