溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何進行Oracle IOT的日常維護與應用

發(fā)布時間:2021-11-08 16:37:58 來源:億速云 閱讀:175 作者:柒染 欄目:建站服務器

這篇文章給大家介紹如何進行Oracle IOT的日常維護與應用,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

 

 

IOT日常維護

 

相對于堆表heap結構,索引組織表最大的特點在于將數(shù)據(jù)行全部內容作為葉子節(jié)點保存在索引結構中。IOT中只包括索引段(Index Segment)結構,沒有對應的數(shù)據(jù)表段(Table Segment)結構。

 

在日常運維工作中,我們經(jīng)常需要對索引結構進行定期的重構rebuild操作,來消除索引無效節(jié)點(Dead Node)。那么,IOT結構中,我們維護工作需要注意些什么問題呢?

 

我們依然使用上篇的IOT數(shù)據(jù)表T_IOT和堆表T_HEAP來進行比對實驗。

 

 

SQL> select index_name from user_indexes where table_name='T_IOT';

 

INDEX_NAME

------------------------------

SYS_IOT_TOP_75124

 

 

數(shù)據(jù)表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

 

 

我們刪除一批數(shù)據(jù),形成死葉子節(jié)點。

 

 

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

 

 

數(shù)據(jù)行被刪除,索引段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視圖中,我們可以清晰看到有接近四萬葉子節(jié)點是Dead狀態(tài),索引樹高度為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索引也沒有辦法實現(xiàn)。整理IOT的方法,可以選擇數(shù)據(jù)表的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

 

 

整理數(shù)據(jù)表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

 

 

從分析結果看,我們消除了死葉子節(jié)點。那么,我們是否可以對數(shù)據(jù)表開啟row movement呢?這個操作是move操作的替代品。

 

 

SQL> alter table t_iot enable row movement;

alter table t_iot enable row movement

 

ORA-14066: 未分區(qū)的索引表的選項非法

 

SQL> alter table t_heap enable row movement;

Table altered

 

 

從實驗結果看,row movement不能應用到IOT上。

 

 

5IOT Index Overflow Segment

 

IOT表而言,我們需要考慮Overflow Segment的問題。B樹索引葉子節(jié)點存在一個長期讓我們爭議的問題,就是葉子塊分裂、合并的問題。

 

索引結構成樹過程和維持過程,是一個索引樹不斷分裂葉子節(jié)點、拷貝數(shù)據(jù)的過程。當一個新葉子節(jié)點值加入索引樹的時候,索引結構需要將其有序的分配在特定的葉子“位置”上。這點和堆表heap table的隨機保存策略差異很大。如果這個位置所在的數(shù)據(jù)塊已經(jīng)寫“滿”,就需要進行數(shù)據(jù)塊分裂(5/5算法或者9/1算法),找一個新的空白塊,將溢出的數(shù)據(jù)葉子節(jié)點信息寫入到新塊中。這個過程同時伴隨著分支節(jié)點的調整。

 

維持B樹平衡過程是很復雜的過程,一般數(shù)據(jù)表為了維持對應索引的同步結構通常要損失一個數(shù)量級的DML操作效率。

 

對于IOT來說,這種B樹平衡過程代表更加復雜的消耗。因為IOT表的所有數(shù)據(jù)行都要保存在葉子塊中,維持樹過程中的拷貝和分裂操作更加劇烈。Oracle為了緩解這個情況,引入了IOT Overflow Segment概念。

 

通常來說,我們使用IOT表是需要進行考量的。我們很傾向選擇數(shù)據(jù)主鍵列相對較大,列數(shù)相對較少的數(shù)據(jù)表作為IOT表。同時,讀多寫少也是IOT的重要定性指標。

 

Overflow Segment(溢出段)的理念很簡單,通過設置一個閾值(PCTThreshold),來規(guī)定將數(shù)據(jù)行轉移存儲位置。如果我們將PCTThreshold值設置為10,那么如果一個數(shù)據(jù)行空間占有比例超過了10%數(shù)據(jù)塊大小,非主鍵列都會被“溢”出到IOT索引之外進行保存。這個溢出空間我們稱之為“Overflow Segment”,我們也可以為溢出段指定單獨的表空間進行保存。

 

Overflow Segment存在的表空間,我們稱之為Overflow Segment Tablespace。下面我們創(chuàng)建一個全新的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

 

 

數(shù)據(jù)表段(本質是索引段)所在表空間指定,是通過organization index tablespace指定的。Pctthreshold參數(shù)來指定溢出段閾值,我們試驗中設置為5%。溢出段overflow segment通過overflow tablespace來指定。

 

裝載約7萬余條數(shù)據(jù)之后,我們檢查數(shù)據(jù)段的情況。

 

 

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

 

 

在數(shù)據(jù)表視圖中,我們發(fā)現(xiàn)IOT_NAME中對應IOT數(shù)據(jù)表名稱的對象中,存在一個特殊的隱含數(shù)據(jù)表,命名為系統(tǒng)自動命名。這個數(shù)據(jù)表和IOT不同,明確表示存在表空間EXAMPLE中,IOT_TYPE也明確標注出IOT_OVERFLOW類型。

 

我們從段空間分配的角度,看IOTT_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表的空間使用情況:索引段是有空間分配的、溢出段也是有空間分配的。而且兩者可以在不同的表空間。

 

 

參數(shù)pctthreshold是可以指定這個溢出段閾值。如果不指定,Oracle會選擇一個默認值50%。我們的IOTt_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的日常維護與應用就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內容。

AI