In-Memory Column Store

使用In-Memory Column Store
从Oracle 12.1.0.2开始可以使用In-Memory Column Store。In-Memory Column Store对于SGA是一个可选部分用来存储表,表分区与其它数据库对象副本。在In-Memory Column Store中,数据是以列式被加载而不是像SGA中其它部分的数据是以行式被加载,并且数据被优化用于快速扫描。

In-Memory Column Store在SGA中是一个新的静态内存池。在In-Memory Column Store中所存储的数据不是使用传统行格式而是使用列式。每个列作为单独的结构进行存储。In-Memory Column Store不会替代buffer cache,是对buffer cache的一种补充,因此数据在内存中可以以行与列的形式进行存储。为了启用In-Memory Column Store,必须将inmemory_size参数设置为非零值。

可以在以下级别启用In-Memory Column Store
.列
.表
.物化视图
.表空间
.分区

如果在表空间级别启用In-Memory Column Store,那么所有存储在该表空间中的所有表与物化视图将抽默认启用In-Memory Column Store。可以将一个数据库对象的所有列或者将一个数据库对象的部分列加载到In-Memory Column Store中。类似地,对于分区表或物化视图,可以将所有分区或部分分区加载到In-Memory Column Store中。

在In-Memory Column Store中存储数据库对象可以显然提高对数据库对象执行以下类型操作的性能:
.查询扫描大量数据并且使用=,< ,>与in操作来进行过滤
.查询从表中或者从有大量列的物化视图中选择少量列,比如从有100列的表中选择5列
.查询对小表与大表进行关联
.查询将聚集数据

通常情况下,创建多列索引可以提高分析与报告查询的性能。这些索引可能影响DML语句的性能。当数据库对象被加载到In-Memory Column Store中,用于分析或报告查询的索引可以被减少或消除而不会影响查询的性能。消除这些索引可以提高事务和数据加载操作的性能。

可以通过对以下语句增加inmemory子句的方式来对数据库对象启用In-Memory Column Store:
.create table
.alter table
.create tablespace
.alter tablespace
.create materialized view
.alter materialized view

为了判断那个数据库对象被加载到In-Memory Column Store中,可以查询v$in_segments视图:

SQL> alter table jy inmemory;
Table altered

SQL> 
SQL> SELECT OWNER, SEGMENT_NAME, INMEMORY_PRIORITY, INMEMORY_COMPRESSION   FROM V$IM_SEGMENTS;
OWNER                                                                            SEGMENT_NAME                                                                     INMEMORY_PRIORITY INMEMORY_COMPRESSION
-------------------------------------------------------------------------------- -------------------------------------------------------------------------------- ----------------- --------------------

SQL> 
SQL> SELECT OWNER, SEGMENT_NAME, INMEMORY_PRIORITY, INMEMORY_COMPRESSION   FROM V$IM_SEGMENTS;
OWNER                                                                            SEGMENT_NAME                                                                     INMEMORY_PRIORITY INMEMORY_COMPRESSION
-------------------------------------------------------------------------------- -------------------------------------------------------------------------------- ----------------- --------------------

SQL> select count(*) from jy;
  COUNT(*)
----------
     72736

SQL> 
SQL> SELECT OWNER, SEGMENT_NAME, INMEMORY_PRIORITY, INMEMORY_COMPRESSION  FROM V$IM_SEGMENTS;
OWNER                                                                            SEGMENT_NAME                                                                     INMEMORY_PRIORITY INMEMORY_COMPRESSION
-------------------------------------------------------------------------------- -------------------------------------------------------------------------------- ----------------- --------------------
JY                                                                               JY                                                                               NONE              FOR QUERY LOW

In-Memory Column Store不能对以下操作类型提高性能:
.有复杂谓词的查询
.选择大量列的查询
.返回大量数据行的查询
.使用大表联接的查询

SYS用户的对象并且存储在system或sysaux表空间中,那么这种对象不能被加载到In-Memory Column Store中。

In-Memory Column Store压缩方法
在In-Memory Column Store中,数据是可以被压缩的,并且SQL查询可以直接对压缩数据进行查询。In-Memory Column Store压缩方法有:
no memcompress 数据不会被压缩

memcompress for dml 这种方法只对DML操作的数据进行优化与压缩

memcompress for query low 这种方法将提供最佳的查询性能。这种压缩方法比memcompress for dml所压缩的数据要多但比
memcompress for query high压缩方法所压缩的数据要少。当在create或alter语句中指定inmemory子句但没指定压缩方法时或者当指定memcompress for query而没指定low或high时所使用的缺省值

memcompress for query high 这种方法会提供杰出的查询性能。这种压缩方法所压缩的数据量要比memcompress for query low方法多,但比memcompress for capacity low方法所压缩的数据量少

memcompress for capacity low 这种方法会提供很好的查询性能。这种压缩方法所压缩的数据量要比memcompress for query high方法所压缩的数据量多,但比memcompress for capacity high方法所压缩的数据量少。当指定memcompress for capacity而没有指定low或high时所使用的缺省值

memcompress for capacity high 这种方法提供的查询性能一般,但它的所压缩的数据量最多

SQL> alter table jy inmemory;
Table altered

SQL> 
SQL> SELECT OWNER, SEGMENT_NAME, INMEMORY_PRIORITY, INMEMORY_COMPRESSION
  2  FROM V$IM_SEGMENTS;
OWNER                                                                            SEGMENT_NAME                                                                     INMEMORY_PRIORITY INMEMORY_COMPRESSION
-------------------------------------------------------------------------------- -------------------------------------------------------------------------------- ----------------- --------------------

SQL> 
SQL> SELECT OWNER, SEGMENT_NAME, INMEMORY_PRIORITY, INMEMORY_COMPRESSION
  2  FROM V$IM_SEGMENTS;
OWNER                                                                            SEGMENT_NAME                                                                     INMEMORY_PRIORITY INMEMORY_COMPRESSION
-------------------------------------------------------------------------------- -------------------------------------------------------------------------------- ----------------- --------------------

SQL> select count(*) from jy;
  COUNT(*)
----------
     72736

SQL> 
SQL> SELECT OWNER, SEGMENT_NAME, INMEMORY_PRIORITY, INMEMORY_COMPRESSION
  2  FROM V$IM_SEGMENTS;
OWNER                                                                            SEGMENT_NAME                                                                     INMEMORY_PRIORITY INMEMORY_COMPRESSION
-------------------------------------------------------------------------------- -------------------------------------------------------------------------------- ----------------- --------------------
JY                                                                               JY                                                                               NONE              FOR QUERY LOW

关键字memcompres必须要出现在inmemory后面

SQL> alter table jy  inmemory memcompress for query high;
Table altered

SQL> SELECT OWNER, SEGMENT_NAME, INMEMORY_PRIORITY, INMEMORY_COMPRESSION FROM V$IM_SEGMENTS;
OWNER                                                                            SEGMENT_NAME                                                                     INMEMORY_PRIORITY INMEMORY_COMPRESSION
-------------------------------------------------------------------------------- -------------------------------------------------------------------------------- ----------------- --------------------

SQL> select count(*) from jy;
  COUNT(*)
----------
     72736


SQL> SELECT OWNER, SEGMENT_NAME, INMEMORY_PRIORITY, INMEMORY_COMPRESSION FROM V$IM_SEGMENTS;
OWNER                                                                            SEGMENT_NAME                                                                     INMEMORY_PRIORITY INMEMORY_COMPRESSION
-------------------------------------------------------------------------------- -------------------------------------------------------------------------------- ----------------- --------------------
JY                                                                               JY                                                                               NONE              FOR QUERY HIGH

In-Memory Column Store Data Population Options
当对数据库对象雇用In-Memory Column Store时,可以让数据库来控制数据库对象何时被加载到In-Memory Column Store中,或者可以指定一个优先级别来决定加载队列中数据库对象的优先级。Oracle SQL包含一个inmemory priority子句来对于加载队列提供更多的控制。例如,它可以在加载其它数据库对象的数据之前将更重要或不重要的数据库对象的数据进行加载。

在In-Memory Column Store中对于加载数据库对象提供了以下优先级:
priority none Oracle数据库控制何时将数据库对象的数据加载到In-Memory Column Store中。对这个数据库对象进行扫描会触发将这个对象加载到In-Memory Column Store中。当priority在inmemory子句中没有指定时这是它的缺省级别。例如当对表jy修改In-Memory Column Store的压缩方法后,立即查询这个对象是否被加载到In-Memory Column Store中会发现并没有加载

SQL> alter table jy  inmemory memcompress for query low;
Table altered

SQL> SELECT OWNER, SEGMENT_NAME, INMEMORY_PRIORITY, INMEMORY_COMPRESSION FROM V$IM_SEGMENTS;
OWNER                                                                            SEGMENT_NAME                                                                     INMEMORY_PRIORITY INMEMORY_COMPRESSION
-------------------------------------------------------------------------------- -------------------------------------------------------------------------------- ----------------- --------------------

因为没有指定加载数据库对象的优先级,所以需要执行查询进行扫描来触发将其加载到In-Memory Column Store中

SQL> select count(*) from jy;
  COUNT(*)
----------
     72736

SQL> SELECT OWNER, SEGMENT_NAME, INMEMORY_PRIORITY, INMEMORY_COMPRESSION FROM V$IM_SEGMENTS;
OWNER                                                                            SEGMENT_NAME                                                                     INMEMORY_PRIORITY INMEMORY_COMPRESSION
-------------------------------------------------------------------------------- -------------------------------------------------------------------------------- ----------------- --------------------
JY                                                                               JY                                                                               NONE              FOR QUERY LOW

现在可以看到表jy已经被加载到In-Memory Column Store中了,可以看到inmemory_priority为none

priority low 在优先级为none的数据库对象之前将优先级为low的对象加载到In-Memory Column Store中,但在优先级为medium,high或critical的数据库对象被加载到In-Memory Column Store中之后才会将优先级为low的对象加载到In-Memory Column Store中

priority medium 在优先级为none或low的数据库对象之前将优先级为medium的对象加载到In-Memory Column Store中,但在优先级为high或critical的数据库对象被加载到In-Memory Column Store中之后才会将优先级为medium的对象加载到In-Memory ColumnStore中。

priority high 在优先级为none,low或medium的数据库对象之前将优先级为high的对象加载到In-Memory Column Store中,但在优先级为critical的数据库对象被加载到In-Memory Column Store中之后才会将优先级为medium的对象加载到In-Memory ColumnStore中。

priority critical 在优先级为none,low,medium或high的数据库对象之前将优先级为critical的对象加载到In-Memory Column Store中

当多个数据库对象设置了优先级而不为none时,Oracle数据库将对象的所有数据基于它们的优先级别进行排队来将它们加载到In-Memory Column Store中。优先为critical的对象将会最先被加载,接下来就是优先级为high的对象会被加载,依此类推。如果在In-Memory Column Store中没有足够的空间,那么额外要被加载的对象直到有足够空间之前是不会被加载的。当数据库被重启时,优先级不为none的对象会在数据库启动时被加载到In-Memory Column Store中。对于优先级不为none的数据库对象来说,alter table或alter materialized view DDL语句在DDL语句被记录在In-Memory Column Store之前不会返回执行结果。

下面的例子,创建表t1,在没有设置inmemory属性时,表t1是没有被加载到In-Memory Column Store中的

SQL> create table t1 as select * from jy;
Table created

SQL> select owner, segment_name, inmemory_priority, inmemory_compression from v$im_segments;
OWNER                                                                            SEGMENT_NAME                                                                     INMEMORY_PRIORITY INMEMORY_COMPRESSION
-------------------------------------------------------------------------------- -------------------------------------------------------------------------------- ----------------- --------------------
JY                                                                               JY                                                                               NONE              FOR QUERY LOW

修改表的inmemory属性,并且设置了加载优先级为high,数据压缩为memcompress for query high,在修改完成后,表t1就已经被加载到In-Memory Column Store中了

SQL> alter table t1 inmemory priority high memcompress for query high;
Table altered


SQL> select owner, segment_name, inmemory_priority, inmemory_compression from v$im_segments;
OWNER                                                                            SEGMENT_NAME                                                                     INMEMORY_PRIORITY INMEMORY_COMPRESSION
-------------------------------------------------------------------------------- -------------------------------------------------------------------------------- ----------------- --------------------
JY                                                                               JY                                                                               NONE              FOR QUERY LOW
JY                                                                               T1                                                                               HIGH              FOR QUERY HIGH

优先级的设置必须应用给整个表或一个表分区。对表中的不同列集合指定不同的In-Memory Column Store加载优先级别是不允许的。如果一个段在磁盘上的大小为64KB或者更小,那么这个对象不会被加载到In-Memory Column Store中。因此对于一些较小的对象虽然启用了In-Memory Column Store,但可能并不会被加载到In-Memory Column Store中。

In-Memory Column Store相关的初始化参数
inmemory_size:这个参数设置实例中的In-Memory Column Store的大小,它的缺省值为0,这意味着没有雇用In-Memory Column Store。为了雇用In-Memory Column Store这个参数必须设置为非0值。如果这个参数设置为非0值,那么它的最小值为100M。

在多租户环境中,在root容器中设置这个参数是对整个CDB生效的。这个参数也可以对每个PDB进行设置来限制每个PDB中的In-Memory Column Store的大小。PDB的In-Memory Column Store的总大小可以小于,等于或大于CDB的值。然而CDB所设置的In-Memory Column Store的大小是整个CDB中,包含root与所有PDB的In-Memory Column Store可以使用的最大内存,这意味着PDB可以CDB中所有可以使用的In-Memory Column Store的内存。

inmemory_force:这个参数可以对表与物化视图启用In-Memory Column Store或者对表与物化视图禁用In-Memory Column Store,设置这个参数为default,这是它的缺省值,它将允许通过单个对象的inmemory或no inmemory属性来决定是否将对象加载到In-Memory Column Store中。将这个参数设置为off来指定所有表与物化视图将禁用In-Memory Column Store.

inmemory_clause_default:这个参数能让你对新表与物化视图指定一个缺省的In-Memory Column Store子句。不设置这个参数或者设置为一个空字符串来指定对于新表与物化视图不存在缺省的In-Memory Column Store子句。将这个参数设置为no inmemory与它的缺省值(空字符串)有相同的作用。将这个参数设置为有效的inmemory子句来指定它为所有新表与物化视图的In-Memory Column Store的缺省值。这个子句可以包含In-Memory Column Store压缩方法与数据加载选项。如果子句以inmemory开头,那么所有新表与物化视图,包含那些没有inmemory子句的对象,将会被加载到In-Memory Column Store中。如果子句忽略了inmemory,那么它只会对在创建时指定了inmemory子句的新表与物化视图雇用In-Memory Column Store。

inmemory_query:这个参数指定是否允许in-memory查询。将这个参数设置为enable,它是缺省值,允许查询所访问的对象被加载到In-Memory Column Store中,将这个参数设置为disable来禁止将查询所访问的对象加载到In-Memory Column Store中。

inmemory_max_populate_servers:这个参数指定执行In-Memory Column Store加载操作的后台加载服务器进程的最大数量,因此这些服务器进程不能超过系统所能承受的负载。基于系统中的CPU内核数来设置一个合理值。

inmemory_trickle_repopulate_servers_percent:这个参数用来限制用于In-Memory Column Store重新加载的后台加载服务器进程的最大数量,trickle repopulation被设计只占加载服务器进程总数量的很小百分比。这个参数的值为
inmemory_max_populate_servers参数值的一个百分比。例如,如果这个参数设置为10,并且inmemory_max_populate_servers被设置为10,那么将会有一个cpu内核用于tricle repopulation操作。

optimizer_inmemory_aware:这个参数用来启用或禁用优化器成本模型来增强In-Memory Column Store。将这个参数设置为false,将造成优化器在优化SQL语句时忽略有in-memory属性的表。

对数据库启用In-Memory Column Store
在表,表空间或物化视图被启用In-Memory Column Store之前,必须对数据库启用In-Memory Column Store。对数据库启用In-Memory Column Store需要执行以下步骤:
1.确保数据库的兼容性参数设置为12.1.0或更高版本。
2.将inmemory_size参数设置为非零值。当对spfile参数文件设置这个参数时,可以使用alter system语句,并且必须指定scope=spfile,它的最小值为100M。
3.重启数据库,为了在SGA中初始化In-Memory Column Store必须要重启数据库。
4.可选操作,可以执行下面的语句来检查当前为In-Memory Column Store所分配的内存大小。

SQL> show parameter inmemory_size

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
inmemory_size                        big integer 1G

对表启用与禁用In-Memory Column Store
通过对create table或alter table语句指定inmemory子句来对表启用In-Memory Column Store。通过对create table或alter table语句指定no inmemory子句对表禁用In-Memory Column Store。

为了对表启用与禁用In-Memory Column Store,需要执行以下步骤:
1.确保数据库已经启用了In-Memory Column Store
2.使用有合适权限的用户连接到数据库并创建或修改表
3.执行create table或alter table并指定inmemory或no inmmeory子句

创建表并启用In-Memory Column Store
下面的例子将创建一个名叫test_inmem的表并启用In-Memory Column Store

SQL> create table test_inmem(id number(5) primary key,test_col varchar2(15)) inmemory;

Table created.

这个例子对inmemory子句使用缺省值。因此将使用memcompress for query与priority none

对表启用In-Memory Column Store
下面的例子将对表oe.product_information表启用In-Memory Column Store:

SQL> alter table oe.product_information inmemory;

Table altered.

这个例子对inmemory子句使用缺省值。因此将使用memcompress for query与priority none

对表启用In-Memory Column Store并且指定压缩方法为for capacity low
下面的例子对表oe.product_information启用In-Memory Column Store并且指定压缩方法为for capacity low:

SQL> alter table oe.product_information inmemory memcompress for capacity low;

Table altered.

这个例子对priority子句使用缺省值,因此优先级为priority none。

对表启用In-Memory Column Store并且指定数据加载优先级为high
下面的例子对表oe.product_information启用In-Memory Column Store并且指定数据加载优先级为priority high

SQL> alter table oe.product_information inmemory priority high;

Table altered.

这个例子对memcompress子句使用缺省值,因此压缩方法为memcompress for query

对表启用In-Memory Column Store并且指定压缩方法为for capacity high,数据加载优先级为low
下面的例子对表oe.product_information启用In-Memory Column Store并且指定压缩方法为for capacity high,数据加载优先级为priority low

SQL> alter table oe.product_information inmemory  memcompress for capacity high priority low;

Table altered.

对表中的列启用In-Memory Column Store
下面的例子对表oe.product_information表中的一些列启用In-Memory Column Store而剩余的列不雇用。并且对不同的列子集启用不同的In-Memory Column Store压缩方法。

SQL> alter table oe.product_information
  2  inmemory memcompress for query (product_id, product_name, category_id, supplier_id, min_price)
  3  inmemory memcompress for capacity high (product_description, warranty_period, product_status, list_price)
  4  no inmemory (weight_class, catalog_url);

Table altered.

在这个例子中定义如下
以product_id开始至min_price结束的字段列表启用了In-Memory Column Store并且指定压缩方法为memcompress for query.

以product_description开始至list_price结束的字段列表启用了In-Memory Column Store并且指定压缩方法为memcompress for
capacity high

字段weight_class与catalog_url没有启用In-Memory Column Store。

在这个例子中对于priority子句使用了缺省值。因此将使用priority none。可以查询v$in_column_level视图,注意优先级的设置
必须应用给整个表或表分区。对不同字段列表指定不同的优先级是不允许的。

对表禁用In-Memory Column Store
为了对表禁用In-Memory Column Store,只需使用no inmemory子句。下面将对表oe.product_information禁用In-Memory Column Store:

SQL> alter table oe.product_information no inmemory;

Table altered.

对表空间启用与禁用In-Memory Column Store
在使用create tablespace语句来创建表空间时可以通过指定inmemory子句来让表空间启用In-Memory Column Store。也可以使用包含inmemory子句的alter tablespace语句来修改表空间让其启用In-Memory Column Store。

通过执行包含no inmemory子句的create tablespace或alter tablespace语句来对表空间禁用In-Memory Column Store。

当表空间启用In-Memory Column Store之后,存储在该表空间中的所有表与物化视图会默认启用In-Memory Column Store。对于表,物化视图与表空间inmemory子句是相同的。当对表空间启用In-Memory Column Store时在inmemory子句之前,并且当对表空间禁用In-Memory Column Store时在no inmemory子句之前需要使用default存储子句。

当表空间启用In-Memory Column Store后,存储在表空间中的单个表与物化视图可以有不同的in-memory设置,并且单个对象的设置会覆盖表空间级别的设置。例如,如果表空间对于数据加载优先级设置为priority low,但在表空间中的表的数据加载优先级设置为priority high,那么表将使用priority high。

为了对表空间启用或禁用In-Memory Column Store,执行以下操作:
1.确保对数据库启用了In-Memory Column Store。
2.使用有合适权限的用户连接到数据库来创建或修改表空间。
3.执行有inmemory或no inmemory子句的create tablespace或alter tablespace语句

下面的例子将创建一个表空间tbs1并对它启用In-Memory Column Store

SQL> create tablespace tbs1 datafile 'tbs1.dbf' size 40m online default inmemory;

Tablespace created.

这个例子对inmemory子句使用了缺省值,因此压缩方法为memcompress for query,数据加载优先级为priority none。

下面的例子将修改表空间tbs1让其启用In-Memory Column Store并且指定数据压缩方法为memcompress for capacity high,数据加载优先级为priority low

SQL> alter tablespace tbs1 default inmemory memcompress for capacity high priority low;

Tablespace altered.

对物化视图启用与禁用In-Memory Column Store
通过执行包含inmemory子句的create materialized view或alter materialized view语句来对物化视图启用In-Memory Column Store。通过执行包含no inmemory子句的ceate materialized view或alter materialized view语句来对物化视图禁用In-Memory Column Store。

为了对物化视图雇用与禁用In-Memory Column Store,需要执行以下操作:
1.确保对数据库启用了In-Memory Column Store。
2.使用有合适权限的用户连接到数据库来创建或修改物化视图。
3.执行包含inmemory或no inmemory子句的create materialized view或alter materialized语句

下面的例子创建一个名叫oe.prod_info_mv的物化视图并且启用In-Memory Column Store:

SQL> create materialized view oe.prod_info_mv inmemory as select * from oe.product_information;

Materialized view created.

这个例子对inmemory子句使用缺省值。因此将使用memcompress for query与priority none

下面的例子将让物化视图oe.prod_info_mv启用In-Memory Column Store并且指定数据加载优先级为priority high

SQL> alter materialized view oe.prod_info_mv inmemory priority high;

Materialized view altered.

Data Pump与In-Memory Column Store
在impdp命令中通过使用transform=inmemory:y选项来导入启用了In-Memory Column Store的数据库对象。使用这个选项,Data Pump将对所有对象保留In-Memory Column Store子句。当transform=inmemory:n时,Data Pump将对对象删除In-Memory Column Store子句。

也可以使用transform=inmemory_clause:string选项来覆盖在dump文件中数据库对象所设置的In-Memory Column Store子句。例如可以使用这个选项来修改被导入对象的In-Memory Column Store的数据压缩方法。

发表评论

电子邮件地址不会被公开。