您好,登录后才能下订单哦!
这篇文章给大家介绍如何进行Oracle IOT的日常维护与应用,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。
IOT日常维护
相对于堆表heap结构,索引组织表最大的特点在于将数据行全部内容作为叶子节点保存在索引结构中。IOT中只包括索引段(Index Segment)结构,没有对应的数据表段(Table Segment)结构。
在日常运维工作中,我们经常需要对索引结构进行定期的重构rebuild操作,来消除索引无效节点(Dead Node)。那么,IOT结构中,我们维护工作需要注意些什么问题呢?
我们依然使用上篇的IOT数据表T_IOT和堆表T_HEAP来进行比对实验。
SQL> select index_name from user_indexes where table_name='T_IOT';
INDEX_NAME
------------------------------
SYS_IOT_TOP_75124
数据表T_IOT对应的主键索引名称为SYS_IOT_TOP_75124。该索引段大致空间为2M。
SQL> desc t_iot;
Name Type Nullable Default Comments
----------- ------------- -------- ------- --------
OBJECT_ID NUMBER(10)
OBJECT_NAME VARCHAR2(100) Y
SQL> select count(*) from t_iot;
COUNT(*)
----------
72638
SQL> select segment_name, bytes/1024/1024 from user_segments where segment_name='SYS_IOT_TOP_75124';
SEGMENT_NAME BYTES/1024/1024
------------------------------ ---------------
SYS_IOT_TOP_75124 2
我们删除一批数据,形成死叶子节点。
SQL> delete t_iot where rownum<40000;
39999 rows deleted
SQL> commit;
Commit complete
SQL> exec dbms_stats.gather_table_stats(user,'T_IOT',cascade => true);
PL/SQL procedure successfully completed
SQL> select segment_name, bytes/1024/1024 from user_segments where segment_name='SYS_IOT_TOP_75124';
SEGMENT_NAME BYTES/1024/1024
------------------------------ ---------------
SYS_IOT_TOP_75124 2
数据行被删除,索引段HWM没有收缩。我们可以使用analyze index命令进行索引健康程度检查。
SQL> analyze index SYS_IOT_TOP_75124 validate structure;
Index analyzed
QL> select height, blocks, name, lf_rows, DEL_LF_ROWS, pct_used from index_stats;
HEIGHT BLOCKS NAME LF_ROWS DEL_LF_ROWS PCT_USED
---------- ---------- ------------------------------ ---------- ----------- ----------
2 256 SYS_IOT_TOP_75124 72638 39999 90
从index_stats视图中,我们可以清晰看到有接近四万叶子节点是Dead状态,索引树高度为2。我们进行索引rebuild,是常用的整理索引操作。
SQL> alter index SYS_IOT_TOP_75124 rebuild;
alter index SYS_IOT_TOP_75124 rebuild
ORA-28650: IOT 中的主索引不能重建
SQL> alter table t_iot disable constraint SYS_IOT_TOP_75124;
alter table t_iot disable constraint SYS_IOT_TOP_75124
ORA-25188: 对于索引表或排序散列簇, 无法删除/禁用/延迟主键约束条件
常用的rebuild操作不能使用在IOT主键索引中,而且disable索引也没有办法实现。整理IOT的方法,可以选择数据表的move方法。
SQL> alter table t_iot move;
Table altered
SQL> exec dbms_stats.gather_table_stats(user,'T_IOT',cascade => true);
PL/SQL procedure successfully completed
SQL> select segment_name, bytes/1024/1024 from user_segments where segment_name='SYS_IOT_TOP_75124';
SEGMENT_NAME BYTES/1024/1024
------------------------------ ---------------
SYS_IOT_TOP_75124 0.6875
整理数据表t_iot move操作后,索引高水位线下降。
SQL> analyze index SYS_IOT_TOP_75124 validate structure;
Index analyzed
SQL> select height, blocks, name, lf_rows, DEL_LF_ROWS, pct_used from index_stats;
HEIGHT BLOCKS NAME LF_ROWS DEL_LF_ROWS PCT_USED
---------- ---------- ------------------------------ ---------- ----------- ----------
2 88 SYS_IOT_TOP_75124 32639 0 89
从分析结果看,我们消除了死叶子节点。那么,我们是否可以对数据表开启row movement呢?这个操作是move操作的替代品。
SQL> alter table t_iot enable row movement;
alter table t_iot enable row movement
ORA-14066: 未分区的索引表的选项非法
SQL> alter table t_heap enable row movement;
Table altered
从实验结果看,row movement不能应用到IOT上。
5、IOT Index Overflow Segment
对IOT表而言,我们需要考虑Overflow Segment的问题。B树索引叶子节点存在一个长期让我们争议的问题,就是叶子块分裂、合并的问题。
索引结构成树过程和维持过程,是一个索引树不断分裂叶子节点、拷贝数据的过程。当一个新叶子节点值加入索引树的时候,索引结构需要将其有序的分配在特定的叶子“位置”上。这点和堆表heap table的随机保存策略差异很大。如果这个位置所在的数据块已经写“满”,就需要进行数据块分裂(5/5算法或者9/1算法),找一个新的空白块,将溢出的数据叶子节点信息写入到新块中。这个过程同时伴随着分支节点的调整。
维持B树平衡过程是很复杂的过程,一般数据表为了维持对应索引的同步结构通常要损失一个数量级的DML操作效率。
对于IOT来说,这种B树平衡过程代表更加复杂的消耗。因为IOT表的所有数据行都要保存在叶子块中,维持树过程中的拷贝和分裂操作更加剧烈。Oracle为了缓解这个情况,引入了IOT Overflow Segment概念。
通常来说,我们使用IOT表是需要进行考量的。我们很倾向选择数据主键列相对较大,列数相对较少的数据表作为IOT表。同时,读多写少也是IOT的重要定性指标。
Overflow Segment(溢出段)的理念很简单,通过设置一个阈值(PCTThreshold),来规定将数据行转移存储位置。如果我们将PCTThreshold值设置为10,那么如果一个数据行空间占有比例超过了10%数据块大小,非主键列都会被“溢”出到IOT索引之外进行保存。这个溢出空间我们称之为“Overflow Segment”,我们也可以为溢出段指定单独的表空间进行保存。
Overflow Segment存在的表空间,我们称之为Overflow Segment Tablespace。下面我们创建一个全新的IOT,设置专门的PCTThreshold值。
SQL> create table t_iotbig
2 (object_id number primary key,
3 object_name varchar2(200),
4 object_type varchar2(100),
5 EDITION_NAME varchar2(100),
6 last_ddl_time date)
7 organization index tablespace users
8 pctthreshold 5
9 overflow tablespace example;
Table created
SQL> insert into t_iotbig select object_id, object_name, object_type, edition_name, last_ddl_time from dba_objects;
72604 rows inserted
SQL> commit;
Commit complete
SQL> exec dbms_stats.gather_table_stats(user,'T_IOTBIG',cascade => true);
PL/SQL procedure successfully completed
数据表段(本质是索引段)所在表空间指定,是通过organization index tablespace指定的。Pctthreshold参数来指定溢出段阈值,我们试验中设置为5%。溢出段overflow segment通过overflow tablespace来指定。
装载约7万余条数据之后,我们检查数据段的情况。
SQL> col tablespace_name for a10;
SQL> col iot_name for a10;
SQL> select table_name, tablespace_name, num_rows, iot_type, iot_name from dba_tables where wner='SYS' and table_name='T_IOTBIG';
TABLE_NAME TABLESPACE NUM_ROWS IOT_TYPE IOT_NAME
------------------------------ ---------- ---------- ------------ ----------
T_IOTBIG 72604 IOT
SSQL> select index_name, index_type, PCT_THRESHOLD, tablespace_name from dba_indexes where table_name='T_IOTBIG' and wner='SYS';
INDEX_NAME INDEX_TYPE PCT_THRESHOLD TABLESPACE
------------------------------ --------------------------- ------------- ----------
SYS_IOT_TOP_75137 IOT - TOP 5 USERS
索引具备属性pct_threshold=5。同时,我们在dba_tables中,可以看到溢出段的情况。
SQL> select table_name, tablespace_name, iot_name, iot_type from dba_tables where wner='SYS' and iot_name='T_IOTBIG';
TABLE_NAME TABLESPACE IOT_NAME IOT_TYPE
------------------------------ ---------- ---------- ------------
SYS_IOT_OVER_75137 EXAMPLE T_IOTBIG IOT_OVERFLOW
在数据表视图中,我们发现IOT_NAME中对应IOT数据表名称的对象中,存在一个特殊的隐含数据表,命名为系统自动命名。这个数据表和IOT不同,明确表示存在表空间EXAMPLE中,IOT_TYPE也明确标注出IOT_OVERFLOW类型。
我们从段空间分配的角度,看IOT表T_IOTBIG的情况。
SQL> select segment_name, segment_type, tablespace_name, extents, blocks from dba_segments where wner='SYS' and segment_name in ('SYS_IOT_OVER_75137','SYS_IOT_TOP_75137','T_IOTBIG');
SEGMENT_NAME SEGMENT_TYPE TABLESPACE EXTENTS BLOCKS
-------------------- ------------------ ---------- ---------- ----------
SYS_IOT_TOP_75137 INDEX USERS 20 640
SYS_IOT_OVER_75137 TABLE EXAMPLE 1 8
从dba_segments中,可以清楚看到IOT表的空间使用情况:索引段是有空间分配的、溢出段也是有空间分配的。而且两者可以在不同的表空间。
参数pctthreshold是可以指定这个溢出段阈值。如果不指定,Oracle会选择一个默认值50%。我们的IOT表t_iot就是这样的方式。
SQL> select index_name, index_type, PCT_THRESHOLD, tablespace_name from dba_indexes where table_name='T_IOT' and wner='SYS';
INDEX_NAME INDEX_TYPE PCT_THRESHOLD TABLESPACE
------------------------------ --------------------------- ------------- ----------
SYS_IOT_TOP_75124 IOT - TOP 50 SYSTEM
SQL> select count(*) from dba_tables where wner='SYS' and iot_name='T_IOT';
COUNT(*)
----------
0
关于如何进行Oracle IOT的日常维护与应用就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。