1 In-Memory Column Store 说明
从Oracle 12.1.0.2 开始,开始支持In-Memory Column Store 特性,即在SGA 中在单独开辟一块内存空间,以列存储的方式来存储对象,从而提升扫描的性能。 IM column 存储并不能代替buffer cache,而是对内存区域的一个补充。
Oracle dual-format 架构允许数据同时存储在 buffer cache(row format) 和 In memory Area (in-memory column format) 中,但Oracle 并不需要2倍的内容空间,in-memroy column format 会根据对象的大小,加载在内存中,但buffer cache 所需要的内存空间就会小很多。
在dual-format架构下,数据物理上还是保存一份,所以数据库会自动维护row 和 column format 的数据一致性,就像维护表和索引一致性一样。
In-Memory area 是在SGA中的一个区域,其大小由初始化参数INMEMORY_SIZE决定,默认为0,可以通过V$SGA视图查看大小。In-Memory area是一个静态区域,其大小不受AMM管理,如果修改INMEMORY_SIZE参数,必须重启实例才能生效,如果启用该特性,那么INMEMORY_SIZE最小值是100M。
SQL> show parameter INMEMORY NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ inmemory_clause_default string inmemory_force string DEFAULT inmemory_max_populate_servers integer 0 inmemory_query string ENABLE inmemory_size big integer 0 inmemory_trickle_repopulate_servers_ integer 1 percent optimizer_inmemory_aware boolean TRUE
In-Memory area 分成2个小pool:
1.1MB 的pool,实际用来存储column formatted data。
2.64K pool,用来存储IM column store中对象的metadata。
可以通过V$INMEMORY_AREA视图查看具体内存的分配情况:
SQL> select * from v$inmemory_area; POOL ALLOC_BYTES USED_BYTES POPULATE_STATUS CON_ID -------------------------- ----------- ---------- -------------------------- ---------- 1MB POOL 0 0 OUT OF MEMORY 1 64KB POOL 0 0 OUT OF MEMORY 1 1MB POOL 0 0 OUT OF MEMORY 2 64KB POOL 0 0 OUT OF MEMORY 2 1MB POOL 0 0 OUT OF MEMORY 3 64KB POOL 0 0 OUT OF MEMORY 3 6 rows selected.
可以在以下级别启用IM column store:
1. Column 2. Table 3. Materialized view 4. Tablespace 5. Partition
比如在表空间级别启用IM column store,那么该表空间下的所有表和物化视图都会启用IM column store。
采用IM column store的对象,在如下操作下,会大幅提升性能:
1. A query that scans a large number of rows and applies filters that use operators such as the following: =, <, >, and IN 2. A query that selects a small number of columns from a table or materialized view with a large number of columns, such as a query that selects five columns from a table with 100 columns 3. A query that joins a small table to a large table 4. A query that aggregates data
可以通过以下语法启用IM column store:
1. CREATE TABLE 2. ALTER TABLE 3. CREATE TABLESPACE 4. ALTER TABLESPACE 5. CREATE MATERIALIZED VIEW 6. ALTER MATERIALIZED VIEW
可以通过v$IM_SEGMENTS 视图查看当前哪些对象正在IM column store:
SQL> SELECT OWNER, SEGMENT_NAME, INMEMORY_PRIORITY, INMEMORY_COMPRESSION FROM V$IM_SEGMENTS;
在如下操作下,IM column store 不会提升性能:
1. Queries with complex predicates 2. Queries that select a large number of columns 3. Queries that return a large number of rows 4. Queries with multiple large table joins
注意:
1. SYS 用户的对象,或者存储在SYSTEM,SYSAUX 表空间的对象不支持IM column store。
2. 在12c RAC环境中, 启用IN MEMORY特性,需要设置parallel_degree_policy=AUTO和parallel_force_local=false否则只是执行计划中的启用,优化器感知不到全局IM的情况。
SQL> alter system set parallel_force_local=false sid='*'; System altered. SQL> alter system set parallel_degree_policy=AUTO sid='*'; System altered.
2 IM Column Store Data Population
在对Oracle 对象启用IM Column store时,可以使用默认的数据populated级别,即在数据第一次扫描的时候,才会加载到IM 中。 也可以指定population的级别。 在启用IM 的语法中,INMEMORY PRIORITY 选项可以控制级别。
如:
ALTER TABLE CNDBA.CN INMEMORY PRIORITY CRITICAL;
可以选择的级别如下:
当数据库重启之后,所有优先级别不是NONE的对象,都会在启动的时候自动加载到IB column store。加载过程会根据优先级来操作。 先加载CRITICAL的,最后到LOW,在最后是NONE。 但因为IM 空间有限,当没有足够IM空间来存储对象时,那么其他还有存储到IM的对象都不能加入。
在IM 加载的时候,算法会自动判断是单实例还是RAC, 如果是RAC 环境,默认采用NO DUPLICATE,即整个集群只维护一份数据,每个对象是分布存在在所有节点上。
比如在一个3节点的RAC 中,实例1存储2013年的分区数据,节点2存储2014年的数据,节点3存储2015年的数据。
为了增加数据的可靠性,可以使用DUPLICATE ALL选项,指定每个in-memory 会在每个实例上都保存一份。如IM 对象cndba,在3节点的RAC中,每个节点上都会保存一份cndba,每个节点都可以进行数据查询,当然,Oracle 内部机制会维护不同节点之间的数据一致性。
除了DUPLICATE ALL 之外,还可以设置为DUPLICATE,即在不同的2个节点上,各保留一份。 假设对象还是CNDBA,还是3节点的RAC,那么实例1和实例3上可以保留CNDBA的IM数据。 在这种情况下,就会区分primary 和 backup的角色,但2个角色都可以进行查询,这种角色的区别,主要还是管理机制上的考虑。当primary database 实例挂掉之后,存活的backup就会变成primary。
3 In-Memory Columnar Compression
一般情况下,压缩的主要目的是为了节省空间,但是在IM column store中,压缩采用了新的算法,不仅可以节省内存空间,也可以提升查询性能。
新的Oracle IM 压缩格式直接对压缩列进行查询,即只需要对更少的数据进行扫描和过滤,只有在返回结果集时才需要进行解压缩。
IM压缩级别可以通过INMEMORY MEMCOMPRESS指定,目前版本一共有6种压缩级别,具体如下:
默认情况下,采用FOR QUERY LOW,提供最大的查询性能。 根据数据类型和内容的不同,压缩率在2X- 20X。 压缩可以在单表中跨列或分区进行,比如某些列需要查询性能,某些列需要节省空间,示例如下:
CREATE TABLE cndba ( c1 NUMBER, c2 NUMBER, c3 VARCHAR2(10), c4 CLOB ) INMEMORY MEMCOMPRESS FOR QUERY NO INMEMORY(c4) INMEMORY MEMCOMPRESS FOR CAPCITY HIGH(c2);
根据上面的说明,可以看出,IM 压缩和 Hybrid Columnar Compression(HCC) 很类似,但区别是IM 压缩只能在内存中进行,而HCC 是针对整个disk 存储的。
4 IM Column Store 的Scan Optimization
在SQL语句查询时,Columnar format 只查询需要的列,所以能提升性能,如一下SQL:
SELECT cust_id, time_id, channel_id FROM sales WHERE prod_id > 14 AND prod_id < 29
在使用buffer cache时,典型的流程是,数据库通过扫描索引查询prod_id,然后使用rowid 从硬盘获取rows记录,加载到buffer cache,然后丢弃掉不用的列数据。
如果使用IM column store,数据库只需要扫描需要的列即可,不需要扫描物理磁盘。
另外,IM column store 还使用了内部的storage index 来过滤数据,进一步减少了扫描的数量。 Storage index 里保存了每个in-memory compression unit中最小和最大值,因此数据库可以利用storage index过滤,然后只扫描需要的数据,在我们的示例中,假设storage index 有4个unit,那么就只需要后2个,扫描满足WHERE prod_id > 14 AND prod_id < 29即可。
关于In-Memory Column store的理论部分先整理这么多,下篇演示操作。
版权声明:本文为博主原创文章,未经博主允许不得转载。