十
11
IMO特性的重要参数
- inmemory_size:IM内存池大小。缺省值为0,不启用IM池,IM池最小值为100M。
- inmemory_query:查询操作是否启用IMO特性,ENABLE为启用,DISABLE为禁用。
- inmemory_clause_default:设置IMO的缺省配置,默认为空。
- inmemory_force:是否开启强制使用IMO特性。
- inmemory_max_populate_servers:IM加载数据的后台进程(Wnnn)数量。
- inmemory_trickle_repopulate_servers_percent:涓流重载的工作量比,取值范围为0~50,如果设置为10,则重载工作量占后台进程总工作量的10%。
- optimizer_inmemory_aware:是否开启优化器基于IMO的支持。
IMO列式压缩的级别
- IMO进行列式压缩后,大致可以获得2~20倍的空间节省,不仅取决于压缩级别选项,同样依赖于数据本身的特点。
- MEMCOMPRESS FOR CAPACITY HIGH虽然压缩比最大,但在查询性能上不会有太大的劣势。
- 非必要情况,尽可能选择默认的NONE级别,提升数据库启动过程的效率。
- 对于必要加载对象,可以选择非繁忙时段,手工触发加载,因为加载过程会有较高的CPU开销。
表创建过程中,添加IM属性:
- 给表添加INMEMORY属性,默认整表MEMCOMPRESS FOR QUERY LOW加载。
CREATE TABLE test_inmem (id NUMBER, test_col VARCHAR2(15)) INMEMORY;
- 给整表添加INMEMORY属性,给某个列取消INMEMORY属性。
CREATE TABLE myimtab (c1 NUMBER, c2 CHAR(2), c3 DATE) INMEMORY NO INMEMORY (c1);
- 给分区表添加INMEMORY属性,可以给各个分区添加不同的类别属性。
CREATE TABLE prod_part ... PARTITION BY LIST .. ( PARTITION p1 .. INMEMORY, PARTITION p2 .. NO INMEMORY, PARTITION p3 .. PRIORITY HIGH, PARTITION p4 .. MEMCOMPRESS FOR CAPACITY LOW, PARTITION p5 .. , ..);
现有表添加和删除IM属性:
- 给现有表添加INMEMORY属性。
ALTER TABLE product_information INMEMORY;
- 给现有表添加INMEMORY属性。
ALTER TABLE product_information NO INMEMORY;
- 给分区表配置INMEMORY属性。
ALTER TABLE oe.product_information INMEMORY MEMCOMPRESS FOR QUERY ( product_id, product_name ) INMEMORY MEMCOMPRESS FOR CAPACITY HIGH ( product_description ) NO INMEMORY ( weight_class, catalog_url );
列式存储相关视图查询:
- 查询V$INMEMORY_AREA视图查看IM池的大小和状态。
SQL> select pool, 2 round(alloc_bytes / 1024 / 1024 / 1024, 2) alloc_size_gb, 3 round(used_bytes / 1024 / 1024 / 1024, 2) used_size_gb, 4 populate_status 5 from v$inmemory_area; POOL ALLOC_SIZE_GB USED_SIZE_GB POPULATE_STATUS ----------- ------------- ------------ ----------------- 1MB POOL 79.99 18.64 DONE 64KB POOL 19.98 0.03 DONE
- POOL:POOL类别,默认使用的是CHUNK为1M的POOL。
- ALLOC_SIZE_GB:各类别POOL的最大可用空间。
- USED_SIZE_GB:各类别POOL的当前使用量。
- POPULATE_STATUS:工作状态。DONE:已完成,无当前作业;POPULATING:加载作业中;OUT OF MEMORY:内存量不足。
- 查询V$IM_SEGMENTS视图查看IM池中对象的大小、属性和状态。
SQL> select segment_name, 2 round(bytes / 1024 / 1024 / 1024, 2) seg_size, 3 round(inmemory_size / 1024 / 1024 / 1024, 2) inmem_size, 4 round(bytes_not_populated / 1024 / 1024 / 1024, 2) progress_size, 5 inmemory_compression inmemory_comp, 6 populate_status status 7 from v$im_segments; SEGMENT_NAME SEG_SIZE INMEM_SIZE PROGRESS_SIZE INMEMORY_COMP STATUS ----------------- -------- ---------- ------------- ------------------ ---------- ALEX_ID 0 0 0 FOR CAPACITY HIGH COMPLETED ALEX_TEST 46.61 18.59 0 FOR QUERY LOW STARTED
- SEG_SIZE:IM缓存段的行式存储大小
- INMEM_SIZE:IM缓存段的列式存储大小
- PROGRESS_SIZE:尚未转换为列式存储的行式存储大小
- INMEMORY_COMP:列式存储属性
- 查询DBA_TABLES视图查看IM池中对象的属性。
SQL> SELECT table_name, 2 inmemory_compression inmemory_comp, 3 inmemory_priority inmemory_pri, 4 inmemory_distribute, 5 inmemory_duplicate 6 from dba_tables 7 where inmemory_compression is not null; TABLE_NAME INMEMORY_COMP INMEMORY_PRI INMEMORY_DISTRIBUTE INMEMORY_DUPLICATE ----------------- ------------- ------------ ------------------- ------------------ ALEX_TEST FOR QUERY LOW NONE BY PARTITION NO DUPLICATE ALEX_ID FOR QUERY LOW NONE AUTO DUPLICATE ALL
- INMEMORY_PRI:标示在RAC环境下的分布状态。AUTO,BY ROWID RANGE,DUPLICATE,NONE,NULL。
- INMEMORY_DUPLICATE:RAC环境下列式存储的复制设置。NO DUPLICATE,DUPLICATE,DUPLICATE ALL。
- 查询V$IM_COLUMN_LEVEL视图查看IM池中对象列的属性。如果是全表缓存,则视图中无记录。
SQL> SELECT obj_num, segment_column_id, inmemory_compression 2 FROM v$im_column_level; OBJ_NUM SEGMENT_COLUMN_ID INMEMORY_COMPRESSION ---------- ----------------- -------------------------- 95975 1 DEFAULT 95975 2 NO INMEMORY
列式存储加载压缩测试:
- 以测试大表ALEX_TEST为例,各级别压缩比为1.16~6.51,最大未及10倍压缩。
- 从加载速度上来看,开启10个加载进程,加载速度与压缩比呈正比例上升趋势。
通过top命令监视,可见在Wnnn进程进行IM数据加载的过程中,是非常消耗CPU资源的,10个Wnnn进程几乎都独占了一个逻辑CPU。进一步证明了数据加载过程不可以在实例启动时进行。
列式存储压缩比估算方法:
DECLARE l_blkcnt_cmp PLS_INTEGER; l_blkcnt_uncmp PLS_INTEGER; l_row_cmp PLS_INTEGER; l_row_uncmp PLS_INTEGER; l_cmp_ratio PLS_INTEGER; l_comptype_str VARCHAR2(100); comp_ratio_allrows NUMBER := -1; BEGIN dbms_compression.get_compression_ratio( -- Input parameters scratchtbsname => ‘ALEXTBS', ownname => 'ALEX', objname => ‘ALEX_TEST', subobjname => NULL, comptype => dbms_compression.comp_inmemory_query_low, -- Output parameter blkcnt_cmp => l_blkcnt_cmp, blkcnt_uncmp => l_blkcnt_uncmp, row_cmp => l_row_cmp, row_uncmp => l_row_uncmp, cmp_ratio => l_cmp_ratio, comptype_str => l_comptype_str, subset_numrows => dbms_compression.comp_ratio_allrows); dbms_output.Put_line('The IM compression ratio is ' || l_cmp_ratio); END;
- 此方法实际上就是通过进行列式缓存来进行估算,成本开销过大。尽量不要使用。
SQL> select segment_name, 2 round(bytes / 1024 / 1024 / 1024, 2) seg_size, 3 round(inmemory_size / 1024 / 1024 / 1024, 2) inmem_size, 4 round(bytes_not_populated / 1024 / 1024 / 1024, 2) progress_size, 5 inmemory_compression inmemory_comp, 6 populate_status 7 from v$im_segments; SEGMENT_NAME SEG_SIZE INMEM_SIZE PROGRESS_SIZE INMEMORY_COMP POPULATE_STATUS ------------- -------- ---------- ------------- -------------- --------------- CMP3$92937 46.87 14.8 16.23 FOR QUERY LOW STARTED
no comment untill now