内存列存储(IM column store) 是Oracle12.1.0.2版本的主要特点。该特点允许列,表,分区和物化视图在内存中以列格式存储,而不是通常的行格式。数据存在内存中的好处显而易见,而列格式存储非常适合商务智能(BI)产品中的分析查询。
列存储是Oracle企业版的独立许可选项。
1. 简介
内存列存储在SGA中是一个新部分,通过初始化参数INMEMORY_SIZE指定大小。可以选择确定的列,整个表,物化视图或表分区组合存储在该部分。或者,你也可以在表空间层启用内存列存储,从而该表空间中的所有表和物化视图自动启用内存列存储。已对下列命令进行了修改以包括另外的in-memory子句。
CREATE TABLE
ALTER TABLE
CREATE TABLESPACE
ALTER TABLESPACE
CREATE MATERIALIZED VIEW
ALTER MATERIALIZED VIEW
常规用例将在后面展示。
文档中说到如下场景适合内存列存储。
使用"=", "<", ">" and "IN"谓词的大数据量扫描。
只返回很多列的表的少数列的查询。
连接小表和大表的查询。
汇聚数据的查询。
文档也提到该特性不适合以下场景。
有复杂谓词的查询。
返回大量列的查询。
返回大量行的查询。
多个大表连接的查询。
从上可知,需记住的最重要的事是要为决定哪些对象将从中受益负责。如果决定正确,你将看到性能的巨大提升。如果决定错误,你将浪费掉本可被缓冲区使用的大量内存。
2. 开启内存列存储
记住,内存列存储是SGA的一部分,因此,SGA必须能包含你指定的NMEMORY_SIZE参数。在多宿主库环境中,如果任何PDB需要存取内存列存储,INMEMORY_SIZE参数必须在CDB中设置。
1) 如果你正使用AMM (MEMORY_TARGET),将必须扩展它以适应INMEMORY_SIZE参数值。
2) 如果你正使用ASMM (SGA_TARGET),将必须扩展它以适应INMEMORY_SIZE参数值。
假定COMPATIBLE参数设置成12.1.0或更高,且SGA总有足够的空间容纳内存列存储,下列过程将开启内存列存储。这里设置INMEMORY_SIZE参数为2G。
ALTER SYSTEM SET SGA_TARGET=3G SCOPE=SPFILE;
ALTER SYSTEM SET INMEMORY_SIZE=2GSCOPE=SPFILE;
SHUTDOWN IMMEDIATE;
STARTUP;
ORACLE instance started.
Total System Global Area 3221225472 bytes
Fixed Size 2929552 bytes
Variable Size 419433584 bytes
Database Buffers 637534208 bytes
Redo Buffers 13844480 bytes
In-Memory Area 2147483648 bytes
Database mounted.
Database opened.
SQL>
注意,启动期间会显示"In-Memory Area"行。
当前IM相关设置将被如下显示。除了大小,所有其他相关参数均为默认值。
SQL> SHOW PARAMETER INMEMORY
NAME TYPE VALUE
----------------------------------------------- ------------------------------
inmemory_clause_default string
inmemory_force string DEFAULT
inmemory_max_populate_servers integer 1
inmemory_query string ENABLE
inmemory_size big integer 2G
inmemory_trickle_repopulate_servers_integer 1
percent
optimizer_inmemory_aware boolean TRUE
SQL>
除非在PDB级别显式设置INMEMORY_SIZE参数,否则,该参数设置将被所有PDB继承。在PDB级别改变INMEMORY_SIZE参数并不要求重启实例或PDB。
CONN sys@pdb1 AS SYSDBA
-- Disable IM column store in the PDB
ALTER SYSTEM SET INMEMORY_SIZE=0;
-- OR
ALTER SYSTEM RESET INMEMORY_SIZE;
-- Assign a PDB-specific size.
ALTER SYSTEM SET INMEMORY_SIZE=1G;
3. 关闭内存列
根据你的目的,有多种关闭内存列存储的方法。
设置INMEMORY_FORCE参数为"OFF"意味着对象不再被保存在内存列存储中,将其切换回"DEFAULT"将恢复其默认的行为。
-- System level
ALTER SYSTEM SET INMEMORY_FORCE=OFF;
ALTER SYSTEM SET INMEMORY_FORCE=DEFAULT;
设置INMEMORY_QUERY参数为"DISABLE"意味着优化器优化查询时将不再考虑内存列存储。将其切换回"ENABLE"将恢复其默认功能。
-- System level
ALTER SYSTEM SET INMEMORY_QUERY=DISABLE;
ALTER SYSTEM SET INMEMORY_QUERY=ENABLE;
-- Session level
ALTER SESSION SET INMEMORY_QUERY=DISABLE;
ALTER SESSION SET INMEMORY_QUERY=ENABLE;
为了完全禁用内存列存储且释放内存,只需重置INMEMORY_SIZE参数。
ALTER SYSTEM RESET INMEMORY_SIZESCOPE=SPFILE;
SHUTDOWN IMMEDIATE;
STARTUP;
就像前面说的,可以更改PDB级别的设置且不需要实例或PDB重启。
4. 管理表