所谓数据库的列式转换填充,就是数据库从磁盘读取现有的行格式数据,将其转换为列格式,然后再存储到IM列存储中的过程。将数据库对象填充到列式存储会极大地提高访问效率。只有具有In-Memory属性的对象才能够做转换填充。
启用对象的列式填充的目的
IM列存储不会自动将数据库中的所有对象加载到IM列存储中。如果不使用DDL将任何对象指定为INMEMORY,则IM列存储将保持为空。 将用户指定的In-Memory对象的行转换为列格式是必需的,以便它们可用于分析查询。
将磁盘上现有数据转换为列格式的填充与通常所说的列式填充不同,后者只是将新数据加载到IM列存储中。 因为IMCU是只读结构,所以当行更改时,Oracle数据库不会自动填充它们。而前者,则是数据库记录事务日志中的行修改记录,然后创建新的IMCU作为IM的一部分。
列式转换填充的原理
可以指定数据库在实例启动时或访问INMEMORY对象时填充IM列存储中的对象。 列式转换填充算法在单实例数据库和RAC中有所区别。
DDL语句包括一个INMEMORY PRIORITY子句,为子句队列提供更多的控制。
优先级设置适用于整个表,分区或子分区,而不适用于不同的列子集。 在对象上设置INMEMORY属性意味着此对象是IM列存储中的填充的候选项。 这并不意味着数据库会立即填充该对象。 Oracle数据库管理优先级如下:
1、按需填充
默认情况下,INMEMORY PRIORITY参数设置为NONE。 在这种情况下,数据库仅在通过全表扫描访问对象时填充该对象。 如果对象永远不被访问,或者只有通过索引扫描访问或者通过rowid进行访问,则不会发生转换。
2、基于优先级的填充
当PRIORITY设置为非NONE值时,Oracle数据库将使用内部管理的优先级队列自动填充对象。 在这种情况下,全扫描不是填充的必要条件。
基于优先级的填充过程如下:
a、在数据库实例重新启动后,自动填充IM列中的柱状数据
b、基于指定优先级的INMEMORY对象的队列人口
例如,使用INMEMORY PRIORITY CRITICAL更改的表优先于使用INMEMORY PRIORITY HIGH更改的表,该表依次优先于使用INMEMORY PRIORITY LOW更改的表。 如果IM列存储空间不足,则Oracle数据库在空间可用之前不会填充其他对象。
c、等待从ALTER TABLE或ALTER MATERIALIZED VIEW语句返回,直到对象的更改记录在IM列存储中
在IM列存储中填充一个段后,数据库仅在段被删除或移动时才将其推离,或者使用NO INMEMORY属性更新段。 可以手动或通过ADO策略驱逐细分。
在完成此示例之前,必须为数据库启用IM列存储。
1、以管理员身份登录数据库,然后查询客户表,如下所示:
2、显示查询的执行计划:
3、在IM列存储中启用sh.customers表的填充:
4、要确定sh.customers表中的数据是否已在IM列存储中填充,请执行以下查询(包括样本输出):
在这种情况下,由于sh.customers表尚未被扫描,因此在IM列存储中不会填充任何片段。
5、使用与步骤1中相同的语句查询sh.customers:
6、查询游标显示数据库执行完整扫描并访问IM列存储:
7、再次查询V$IM_SEGMENTS(包括样本输出):
8、DBA_FEATURE_USAGE_STATISTICS视图确认数据库使用IM列存储来检索结果:
后台进程如何填充IMCU
在填充期间,数据库以其行格式从磁盘读取数据,枢转行以创建列,然后将数据压缩为内存中压缩单元(IMCU)。
工作进程(Wnnn)填充IM列存储中的数据。 每个工作进程在对象的数据库块的子集上运行。 人口是一种流式传输机制,同时压缩数据并将其转换为柱状格式。
INMEMORY_MAX_POPULATE_SERVERS初始化参数指定要用于IM列存储群体的***工作进程数。 默认情况下,该设置是CPU_COUNT的一半。 将此参数设置为适合您的环境的值。 更多的工作进程导致填充增长,但会占用更多的CPU资源。 更少的工作进程导致人口减少,这降低了CPU开销。
列式填充控制
使用数据定义语言(DDL)语句中的INMEMORY子句来指定哪些对象有资格进入IM列存储。 可以启用表空间,表,分区和物化视图。
INMEMORY子句
INMEMORY是一个段级属性,而不是列级属性。 但是可以将INMEMORY属性应用于特定对象中的列的子集。
要启用或禁用IM列存储的对象,请在以下任何语句中指定INMEMORY子句:
1、CREATE TABLESPACE or ALTER TABLESPACE
默认情况下,表空间中的所有表和实例化视图都对IM列存储启用。 表空间中的单个表和实例化视图可能具有不同的INMEMORY属性。 单个数据库对象的属性将覆盖表空间的属性。
2、CREATE TABLE or ALTER TABLE
默认情况下,IM列存储填充表中的所有非虚拟列。 您可以指定表的全部或一部分列。 例如,您可以将oe.product_information中的weight_class和catalog_url列从资格中排除。 对于分区表,您可以填充IM列存储中的全部或一部分分区。 默认情况下,对于分区表,所有表分区都将继承INMEMORY属性。
3、CREATE MATERIALIZED VIEW or ALTER MATERIALIZED VIEW
对于分区实体化视图,可以填充IM列存储中的所有或一部分分区。
DBA_TABLES视图中的INMEMORY列指示哪些表具有INMEMORY属性设置(ENABLED)或未设置(DISABLED)。
以下对象不符合IM列存储中的填充资格:
索引;索引组织表;哈希集群;由SYS用户拥有并存储在SYSTEM或SYSAUX表空间中的对象。
如果为IM列存储启用了表,并且它包含以下任何类型的列,则这些列将不会在IM列存储中填充:
行列(varrays,嵌套表列和行外LOB)
使用LONG或LONG RAW数据类型的列
扩展数据类型列
对表进行列式填充
假设以用户sh连接到数据库。 可以使用默认压缩级别FOR QUERY LOW(参见“内存中压缩”),为IM列存储中的用户表启用客户表:
列式填充的优先级选项
为IM列存储启用数据库对象时,可以启用Oracle数据库来控制对象在IM列存储中的填充(默认),也可以指定确定对象的优先级。
Oracle SQL包括一个INMEMORY PRIORITY子句,为群体提供了对队列的更多控制。 例如,在填充其他数据库对象的数据之前,填充数据库对象的数据可能更重要或更不重要。
下表说明了支持的优先级。