In-Memory Column Store IM列存储是Oracle 12.1.0.2新引入的特性,IM列存储是系统全局区SGA的一个可选部分,它存储表、表分区或其它数据库对象的副本。IM列存储包含在Oracle数据库In-Memory选项中。本部分内容是在Oracle 12.1.0.2版本进行操作。
1 IM列存储
1.1 IM列存储介绍
IM列存储是SGA中一个新的静态池,IM列存储中的数据不以传统的行格式存储,而是以列格式存储,每个列存储为一个单独的结构。IM列存储并不会替代数据库缓冲区缓存,而是作为它的一个补充,因此数据可以以行和列的格式并存在内存中。
要启用IM列存储,必须将INMEMORY_SIZE初始化参数设置为非零值,最小值为100M。可以在以下任意级别启用列存储特性:
- 列
- 表
- 物化视图
- 表空间
- 分区
1.2 IM列压缩
在IM列存储中,可以对数据进行压缩,并且SQL查询直接在被压缩的数据上执行。IM列存储的压缩方法如下:
在SQL语句中,MEMCOMPRESS关键字之前必须加上INMEMORY关键字。
1.3 IM列存储数据填充
当为IM列存储启用数据库对象时,默认情况下,是由数据库来控制何时在IM列存储中填充数据库对象的数据,当然,也可以通过指定一个优先级别来确定填充填充对列中数据库对象的优先级,SQL语句通过INMEMORY PRIORITY设置优先级别,优先级别包含以下内容:
2 数据库启用IM列存储
在表、表分区、物化视图和表空间启用IM列存储之前,必须为数据库启用IM列存储。数据库启用IM列存储的步骤如下:
1)兼容性设置,确保数据库兼容性是12.1.0或更高级别
SQL> show parameter compatible
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
compatible string 12.1.0.2.0
noncdb_compatible boolean FALSE
2)设置INMEMORY_SIZE初始化参数为非零值,最小为100M
SQL> alter system set inmemory_size=400M scope=spfile;
System altered.
3)重启数据库,初始化SGA中的IM列存储
SQL> startup
ORACLE instance started.
Total System Global Area 1644167168 bytes
Fixed Size 2925024 bytes
Variable Size 973082144 bytes
Database Buffers 234881024 bytes
Redo Buffers 13848576 bytes
In-Memory Area 419430400 bytes
Database mounted.
Database opened.
可以看到出现了一块内存区域;In-Memory Area
4)检查当前为IM列存储分配的内存大小
SQL> show parameter inmemory_size
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
inmemory_size big integer 400M
3 表启用/禁用列存储
对于表的IM列存储的启用和禁用,只需在create table或alter table语句中指定inmemory子句即可。
3.1 IM列存储和非IM列存储比较
1)创建测试表,并统计未使用IM列存储时表的大小
SQL> create table alen.t_objects as select * from dba_objects;
Table created.
SQL> select bytes/1024/1024 from dba_segments where owner='ALEN' and segment_name='T_OBJECTS';
BYTES/1024/1024
---------------
13
2)查看IM内存区域大小
SQL> select * from v$inmemory_area;
POOL ALLOC_BYTES USED_BYTES POPULATE_STATUS CON_ID
-------------------------- ----------- ---------- -------------------------- ----------
1MB POOL 334495744 0 DONE 0
64KB POOL 67108864 0 DONE 0
3)启用IM列存储特性,默认均使用默认值
SQL> alter table alen.t_objects inmemory;
Table altered.
4)查询汇总数据
SQL> select count(1) from alen.t_objects;
COUNT(1)
----------
91690
5)再次查询IM内存区域,发现已经使用,占用的内存列为4M
SQL> select * from v$inmemory_area;
POOL ALLOC_BYTES USED_BYTES POPULATE_STATUS CON_ID
-------------------------- ----------- ---------- -------------------------- ----------
1MB POOL 334495744 4194304 DONE 0
64KB POOL 67108864 131072 DONE 0
SQL> select (4194304+131072)/1024/1024 from dual;
(4194304+131072)/1024/1024
--------------------------
4.125
通过上面的数据可以看出,采用行存储时,占用的空间为13M,而使用IM列存储时,占用的空间为4.125M,空间压缩了30%。
6)查看使用IM列存储时的执行计划
SQL> set autotrace on
SQL> select count(1) from alen.t_objects;
COUNT(1)
----------
91690
Execution Plan
----------------------------------------------------------
Plan hash value: 230482234
---------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
---------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 27 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | TABLE ACCESS INMEMORY FULL| T_OBJECTS | 91690 | 27 (0)| 00:00:01 |
---------------------------------------------------------------------------------
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
3 consistent gets
0 physical reads
0 redo size
544 bytes sent via SQL*Net to client
551 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
3.2 指定IM列存储的压缩方法
对于压缩方法的指定,可以参照上面的表格进行设置。
1)指定capacity high压缩
SQL> drop table alen.t_objects;
Table dropped.
SQL> create table alen.t_objects inmemory memcompress for capacity high as select * from dba_objects;
Table created.
2)查看存储大小
SQL> select * from v$inmemory_area;
POOL ALLOC_BYTES USED_BYTES POPULATE_STATUS CON_ID
-------------------------- ----------- ---------- -------------------------- ----------
1MB POOL 334495744 1048576 DONE 0
64KB POOL 67108864 131072 DONE 0
SQL> select (1048576+131072)/1024/1024 from dual;
(1048576+131072)/1024/1024
--------------------------
1.125
3)查询IM段信息
SQL> select inmemory_size,bytes,inmemory_priority,inmemory_distribute,inmemory_compression from v$im_segments where owner='ALEN' and segment_name='T_OBJECTS';
INMEMORY_SIZE BYTES INMEMORY INMEMORY_DISTRI INMEMORY_COMPRESS
------------- ---------- -------- --------------- -----------------
1179648 13631488 NONE AUTO FOR CAPACITY HIGH
3.3 指定IM列存储的填充优先级
对于IM列存储优先级的指定,可以参照上面的表格进行设置。
1)指定优先级
SQL> drop table alen.t_objects;
Table dropped.
SQL> create table alen.t_objects inmemory memcompress for capacity high priority high as select * from dba_objects;
Table created.
2)查看IM段信息
SQL> select inmemory_size,bytes,inmemory_priority,inmemory_distribute,inmemory_compression from v$im_segments where owner='ALEN' and segment_name='T_OBJECTS';
INMEMORY_SIZE BYTES INMEMORY INMEMORY_DISTRI INMEMORY_COMPRESS
------------- ---------- -------- --------------- -----------------
1179648 13631488 HIGH AUTO FOR CAPACITY HIGH
3.4 启用列级别的IM列存储
对于表中IM列存储的使用,除了在表级,还可以在列级别进行IM列存储的设置。
1)创建列级IM列存储
SQL> alter table alen.t_objects
2 inmemory memcompress for query high(object_name,object_id,data_object_id)
3 inmemory memcompress for capacity high(created)
4 no inmemory(owner,status);
Table altered.
2)查看IM列信息
SQL> select column_name,inmemory_compression from v$im_column_level where owner='ALEN' and table_name ='T_OBJECTS';
COLUMN_NAME INMEMORY_COMPRESSION
------------------------------- --------------------------
OWNER NO INMEMORY
OBJECT_NAME FOR QUERY HIGH
SUBOBJECT_NAME DEFAULT
OBJECT_ID FOR QUERY HIGH
DATA_OBJECT_ID FOR QUERY HIGH
OBJECT_TYPE DEFAULT
CREATED FOR CAPACITY HIGH
LAST_DDL_TIME DEFAULT
TIMESTAMP DEFAULT
STATUS NO INMEMORY
TEMPORARY DEFAULT
COLUMN_NAME INMEMORY_COMPRESSION
------------------------------- --------------------------
GENERATED DEFAULT
SECONDARY DEFAULT
NAMESPACE DEFAULT
EDITION_NAME DEFAULT
SHARING DEFAULT
EDITIONABLE DEFAULT
ORACLE_MAINTAINED DEFAULT
18 rows selected.
3.5 禁用IM列存储
若要禁用表的IM列存储,指定no inmemory即可。
SQL> alter table alen.t_objects no inmemory;
Table altered.
4 表空间启用/禁用列存储
表空间IM列存储的启用和禁用,也是通过inmemory和on inmemory指定。
1)创建表空间
SQL> create tablespace test01 datafile '/u01/app/oracle/oradata/ORCL/test01.dbf' size 100M default inmemory;
Tablespace created.
2)查看表空间属性
select def_inmemory,def_inmemory_priority,def_inmemory_compression,def_inmemory_duplicate from dba_tablespaces where tablespace_name='TEST01';
3)修改表空间IM列存储压缩和填充优先级
SQL> alter tablespace test01 default inmemory memcompress for capacity high priority high;
Tablespace altered.
SQL> select def_inmemory,def_inmemory_priority,def_inmemory_compression,def_inmemory_duplicate from dba_tablespaces where tablespace_name='TEST01';
DEF_INME DEF_INME DEF_INMEMORY_COMP DEF_INMEMORY_
-------- -------- ----------------- -------------
ENABLED HIGH FOR CAPACITY HIGH NO DUPLICATE
以上内容便是对Oracle 12c新特性在数据库、表、列以及表空间的IM列存储的介绍。