In-Memory 列存储
Database In-Memory 使用In-Memory 列存储(IM 列存储),它是Oracle 数据库系统全局区域(SGA) 的一个新组件,称为In-Memory 区域。IM 列存储中的数据以列格式存放。
IM 列存储不会取代缓冲区缓存,而是作为一种补充,以便数据现在可同时以行格式和列格式存储在In-Memory 。In-Memory 区域可分为两个池:一个1MB 池,用于存储填充到In-Memory 的实际列格式数据;一个64K 池,用于存储填充到IM 列存储的对象的元数据。
在V$INMEMORY_AREA视图中可以看到每个池的可用内存量。两个池的相对大小通过内部试探确定,In-Memory 区域的大部分内存分配给1MB 池。
与磁盘上的表空间由多个区段构成一样,IM 列存储由多个In-Memory 压缩单元(IMCU) 构成。每个工作进程分配自己的IMCU,并在其中填充部分数据库块。在填充过程中,数据不以任何特定的方式进行排序或排列。读取数据时以在行格式中出现的顺序进行读取。
启用Oracle inmemory
inmemory_max_populate_server
inmemory_size
从12.2 开始,可以动态增加In-Memory 区域的大小,只需通过ALTER SYSTEM 命令增加INMEMORY_SIZE 参数值即可,但前提是SGA 中有空闲内存。INMEMORY_SIZE参数必须增加128MB 或更多才能让此更改生效。不过,In-Memory 区域的大小不能动态缩小。
将INMEMORY_SIZE参数调小后,必须重启数据库实例才能让更改生效。In-Memory 区域不受Oracle Automatic Memory Management (AMM) 的影响或控制。
#设定inmemory_size,需要重起系统 SQL> ALTER SYSTEM SET INMEMORY_SIZE=1G SCOPE=SPFILE; System altered. SQL> SHOW PARAMETER inmemory; NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ inmemory_adg_enabled boolean TRUE inmemory_automatic_level string OFF inmemory_clause_default string inmemory_expressions_usage string ENABLE inmemory_force string DEFAULT inmemory_max_populate_servers integer 0 inmemory_optimized_arithmetic string DISABLE inmemory_prefer_xmem_memcompress string inmemory_prefer_xmem_priority string inmemory_query string ENABLE inmemory_size big integer 0 inmemory_trickle_repopulate_servers_ integer 1 percent inmemory_virtual_columns string MANUAL inmemory_xmem_size big integer 0 optimizer_inmemory_aware boolean TRUE
#inmemory_max_populate_servers 。该参数设置用于将数据加载到内存的后台进程数量
SQL> alter system set inmemory_max_populate_servers=4;
System altered.
加载对象到inmemory
INMEMORY属性可以在表空间、表、分区、子分区或物化视图上指定。如果在表空间级别启用该属性,默认情况下,相应表空间中的所有新表和物化视图都将启用IM 列存储.
在纯内存数据库中,只有当所有数据都填充到内存后,才可以访问数据库,在填充完成之前数据库不具有可用性。系统会给每个工作进程提供对象的部分数据库块,以填充到IM 列存储。填充是一种流式机制,填充的同时对数据采用列格式并进行压缩。
alter table TEST inmemory (MANDT) no inmemory (OBJCT,AUTH); alter table test no inmemory; #默认情况下,具有INMEMORY属性的对象的所有列都将填充到IM 列存储。但是,如果需要,可以只填充部分列。 ALTER TABLE test INMEMORY NO INMEMORY(MANDT); -- 表的所有列,除去MANDT #对于分区表,表的所有分区都继承In-memory 属性,但也可以只填充部分分区或子分区。 ALTER TABLE sales MODIFY PARTITION SALES_Q1_1998 NO INMEMORY alter tablespace TEST default inmemory; #加载表空间到IM ALTER TABLE test INMEMORY PRIORITY HIGH|MEDIUM|LOW; alter table test inmemory MEMCOMPRESS NO MEMCOMPRESS; alter table test inmemory MEMCOMPRESS FOR DML; alter table test inmemory MEMCOMPRESS FOR QUERY LOW; alter table test inmemory MEMCOMPRESS FOR QUERY high; alter table test inmemory MEMCOMPRESS FOR CAPACITY LOW; alter table test inmemory MEMCOMPRESS FOR CAPACITY HIGH; ##以下没有验证 DBMS_INMEMORY.POPULATE: 强制加载给定的表 DBMS_INMEMORY.REPOPULATE 强制重新加载给定的表,在该表已经至少加载过一次之后才可使用。 EXEC DBMS_INMEMORY.POPULATE('CS','TEST'); EXEC DBMS_INMEMORY.REPOPULATE('CS','TEST', FORCE=>TRUE);
加载的级别
验证
select * from v$im_column_level; select owner,segment_name,segment_type,inmemory_size,bytes,tablespace_name,bytes_not_populated,inmemory_priority from v$im_segments; select pool,ALLOC_BYTES/1024/1024,USED_BYTES/1024/1024,POPULATE_STATUS,con_id from V$INMEMORY_AREA;
SQL> set autotrace traceon
SQL> select count(*) from USRBF2; Execution Plan ---------------------------------------------------------- Plan hash value: 3514332324 ------------------------------------------------------------------------------ | Id | Operation | Name | Rows | Cost (%CPU)| Time | ------------------------------------------------------------------------------ | 0 | SELECT STATEMENT | | 1 | 72 (2)| 00:00:01 | | 1 | SORT AGGREGATE | | 1 | | | | 2 | TABLE ACCESS INMEMORY FULL| test| 1236K| 72 (2)| 00:00:01 | ------------------------------------------------------------------------------ Statistics ---------------------------------------------------------- 222 recursive calls 0 db block gets 239 consistent gets 0 physical reads 0 redo size 553 bytes sent via SQL*Net to client 389 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 17 sorts (memory) 0 sorts (disk) 1 rows processed
限制
数据库中几乎所有对象都可以填充到IM 列存储,但有少数情况除外。以下数据库对象无法填充到IM 列存储:
- 归SYS 用户拥有并存储在SYSTEM 或SYSAUX 表空间中的任何对象
- 索引组织表(IOT)
- 集群表
另外,IM 列存储也不支持以下数据类型:
- LONG(从Oracle Database 8i 开始已弃用)
- 行外LOB
包含这些数据类型的对象的所有其他列可以填充到IM 列存储。仅访问位于IM 列存储中的列的任何查询都将获益于通过列存储访问表数据。如果查询需要不受支持的列中的数据,则将通过行存储执行。小于64KB 的对象不填充到In-Memory ,因为内存是按1MB 块分配的,这些对象会浪费IM 列存储中的大量空间。
In-Memory 压缩的级别
填充到IM 列存储的数据是使用一组新的压缩算法进行压缩的,这些新的压缩算法不仅有助于节省空间,而且还能提高查询性能。这种新的Oracle In-Memory 压缩格式允许直接对压缩的列执行查询。这意味着,所有扫描和筛选都对少得多的数据执行操作。数据只有在结果集需要它们时才会被解压缩。
可以对一个表内的各个列或各个分区使用不同的压缩技术。例如,可以优化表中的一些列以提高扫描速度,而优化其他一些列以节省空间。
CREATE TABLE employees( c1 NUMBER,c2 NUMBER,c3 VARCHAR2(10), c4 CLOB )INMEMORY MEMCOMPRESS FOR QUERYNO INMEMORY(c4)INMEMORY MEMCOMPRESS FOR CAPACITY HIGH(c2)
https://www.oracle.com/technetwork/cn/database/in-memory/overview/twp-oracle-database-in-memory-2245633-zhs.pdf