真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

簡述OracleIOT(IndexOrganizedTable)(下)

 

創(chuàng)新互聯(lián)公司專注于紅寺堡企業(yè)網(wǎng)站建設(shè),響應(yīng)式網(wǎng)站設(shè)計(jì),商城開發(fā)。紅寺堡網(wǎng)站建設(shè)公司,為紅寺堡等地區(qū)提供建站服務(wù)。全流程定制網(wǎng)站,專業(yè)設(shè)計(jì),全程項(xiàng)目跟蹤,創(chuàng)新互聯(lián)公司專業(yè)和態(tài)度為您提供的服務(wù)

下面我們討論一下由于數(shù)據(jù)存儲為索引而帶來的Rowid、Secondary Index問題。

 

6Logical Rowid & Secondary Index

 

IOT的環(huán)境下,我們是不能保證一個(gè)固定的物理Rowid的。

 

堆表(Heap Table)中,一行數(shù)據(jù)被保存在一個(gè)物理位置(file no. + block no.)之后,在正常保存行為中,即使發(fā)生行遷移現(xiàn)象,它的rowid是不會發(fā)生變化的。只有在進(jìn)行數(shù)據(jù)表存儲重構(gòu),如moveshrink space的時(shí)候才會發(fā)生新的rowid賦予。

 

堆表rowid的固定給我們帶來一個(gè)好處,就是連帶的數(shù)據(jù)表索引葉子節(jié)點(diǎn)上面的的rowid永遠(yuǎn)有效的,除非發(fā)生move或者和shrink space操作(此時(shí)索引失效)。

 

但是,IOT存在一些問題。索引葉子節(jié)點(diǎn)的分裂操作是相當(dāng)頻繁的,我們很難保證一個(gè)數(shù)據(jù)行維持在一個(gè)rowid不會發(fā)生大的變化。當(dāng)然,如果我們保證每次訪問數(shù)據(jù)表都是通過主鍵primary key方式,變化的rowid不會有任何影響。問題出在非主鍵的索引,IOT中稱之為“二級索引”Secondary Index上。

 

對于一般的二級索引,如果葉子節(jié)點(diǎn)上保留數(shù)據(jù)行的rowid,那么失效的rowid意味著所有對應(yīng)的二級索引非常容易變?yōu)?FONT face=Calibri>invalid狀態(tài)。

 

在很多數(shù)據(jù)庫版本,包括早期的Oracle版本中,對于Secondary Index是不支持的。最近的oracle中,引入了Logical RowidPhysical Guess的方法,才最終解決了Secondary Index問題。

 

 

SQL> select rowid, object_id from t_iot where rownum<5;

 

ROWID                            OBJECT_ID

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

*BABBVmoCwQP+                            2

*BABBVmoCwQT+                            3

*BABBVmoCwQX+                             4

*BABBVmoCwQb+                            5

 

 

IOT而言,rowid基本上是不合乎我們常見的heap table rowid格式的。我們可以對t_iot添加secondary index。

 

 

SQL> create index idx_t_iot_name on t_iot(object_name);

Index created

 

SQL> exec dbms_stats.gather_table_stats(user,'T_IOT',cascade => true);

PL/SQL procedure successfully completed

 

 

從數(shù)據(jù)字典中看,索引idx_t_iot_name沒有什么額外的差異,只是對于一般索引來說,clustering factor取值略高。

 

 

SQL> select index_Name, index_type, clustering_factor from dba_indexes where wner='SYS' and index_name='IDX_T_IOT_NAME';

 

INDEX_NAME                    INDEX_TYPE                 CLUSTERING_FACTOR

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

IDX_T_IOT_NAME                NORMAL                                 55006

 

SQL> select count(*) from t_iot;

 

 COUNT(*)

----------

    72604

 

 

SQL> select sum(bytes)/1024/1024, count(*) from dba_extents where wner='SYS' and segment_name='IDX_T_IOT_NAME';

 

SUM(BYTES)/1024/1024  COUNT(*)

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

                  4        19

 

 

對于一個(gè)7萬余條記錄的數(shù)據(jù)表索引,占到了19個(gè)分區(qū),總看空間4M。那么,如果是一般的heap table index呢?空間如何?

 

 

SQL> desc t_heap;

Name       Type         Nullable Default Comments

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

OBJECT_ID  NUMBER(10)                             

OBJECT_NAME VARCHAR2(100) Y                        

 

SQL> create index idx_t_heap_name on t_heap(object_name);

 

Index created

 

SQL> select count(*) from t_heap;

 

 COUNT(*)

----------

    72605

 

SQL> select sum(bytes)/1024/1024, count(*) from dba_extents where wner='SYS' and segment_name='IDX_T_HEAP_NAME';

 

SUM(BYTES)/1024/1024  COUNT(*)

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

                  3        18

 

 

相同取值,正常index只有3M空間,約占到18個(gè)分區(qū)。說明:Secondary Index對比一些其他索引,有很多特殊的信息在其中。

 

 

SQL> col object_name for a20;

SQL> select object_id, object_name from dba_objects where object_name in ('IDX_T_HEAP_NAME','IDX_T_IOT_NAME');

 

 OBJECT_ID OBJECT_NAME

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

    75146 IDX_T_HEAP_NAME

    75143 IDX_T_IOT_NAME

 

 

我們嘗試將兩個(gè)索引樹dump出來,探索其結(jié)構(gòu)差異。

 

 

SQL> select value from v$diag_info where name='Default Trace File';

 

VALUE

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

/u01/diag/rdbms/wilson/wilson/trace/wilson_ora_9101.trc

 

--堆表索引結(jié)構(gòu)

SQL> alter system set events 'immediate trace name treedump level 75146';

System altered

 

--IOT表索引結(jié)構(gòu)

SQL> alter system set events 'immediate trace name treedump level 75143';

System altered

 

 

 

首先,我們分析一下一般堆表的索引情況。由于篇幅原因,只截取部分內(nèi)容。

 

 

*** ACTION NAME:(Command Window - New) 2012-10-05 02:43:39.561

 

----- begin tree dump

branch: 0x415c01 4283393 (0: nrow: 2, level: 2)

  branch: 0x415d3b 4283707(-1: nrow: 312, level: 1)

     leaf: 0x415c02 4283394(-1: nrow: 184 rrow: 184)

     leaf: 0x415c03 4283395 (0: nrow: 184 rrow: 184)

     leaf: 0x415c04 4283396 (1: nrow: 188 rrow: 188)

     leaf: 0x415c05 4283397 (2: nrow: 190 rrow: 190)

     leaf: 0x415c06 4283398 (3: nrow: 184 rrow: 184)

     leaf: 0x415c07 4283399 (4: nrow: 186 rrow: 186)

     leaf: 0x415c08 4283400 (5: nrow: 185 rrow: 185)

 

 

Dump結(jié)果上,我們可以清晰看到IDX_T_HEAP_NAME是一個(gè)兩層索引結(jié)構(gòu)。根節(jié)點(diǎn)地址為0x415c01file=1, block=89089)。

 

 

SQL> select to_number('415c01','xxxxxx') from dual;

 

TO_NUMBER('415C01','XXXXXX')

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

                    4283393

 

 

其中的一個(gè)數(shù)據(jù)塊0x415c06進(jìn)行試驗(yàn),轉(zhuǎn)化為十進(jìn)制地址為4283398,二進(jìn)制地址為:10000010101110000000110。根據(jù)rfile解析規(guī)則,最終地址為:file_no=1,block_no=89094

 

 

SQL> alter system dump datafile 1 block 89094;

System altered

 

Dump文件中葉子節(jié)點(diǎn)的內(nèi)容為:

 

row#0[8000] flag: ------, lock: 0, len=32

col 0; len 22; (22):

 2f 31 34 64 63 62 36 32 32 5f 53 79 6e 74 68 4c 61 62 65 6c 55 49

col 1; len 6; (6): 00 41 55 91 00 4b

row#1[7968] flag: ------, lock: 0, len=32

col 0; len 22; (22):

 2f 31 34 64 63 62 36 32 32 5f 53 79 6e 74 68 4c 61 62 65 6c 55 49

col 1; len 6; (6): 00 41 55 91 00 4c

row#2[7928] flag: ------, lock: 0, len=40

col 0; len 30; (30):

 2f 31 34 65 33 63 31 31 32 5f 50 4e 47 45 6e 63 6f 64 65 50 61 72 61 6d 50

 61 6c 65 74 74

col 1; len 6; (6): 00 41 5b 9a 00 9d

 

 

 

從結(jié)構(gòu)上猜測,col0col1分別表示索引列取值和對應(yīng)rowid信息。而IOTsecondary index如何呢?

 

 

*** 2012-10-05 02:43:55.944

----- begin tree dump

branch: 0x4154b9 4281529 (0: nrow: 2, level: 2)

  branch: 0x415acd 4283085 (-1: nrow: 330, level: 1)

     leaf: 0x4154ba 4281530 (-1: nrow: 160 rrow: 160)

     leaf: 0x4154bb 4281531 (0: nrow: 158 rrow: 158)

     leaf: 0x4154bc 4281532 (1: nrow: 163 rrow: 163)

     leaf: 0x4154bd 4281533 (2: nrow: 162 rrow: 162)

     leaf: 0x4154be 4281534 (3: nrow: 163 rrow: 163)

     leaf: 0x4154bf 4281535 (4: nrow: 160 rrow: 160)

     leaf: 0x4154c0 4281536 (5: nrow: 159 rrow: 159)

     leaf: 0x4154c1 4281537 (6: nrow: 161 rrow: 161)

     leaf: 0x4154c2 4281538 (7: nrow: 160 rrow: 160)

 

 

葉子節(jié)點(diǎn)0x4154bc,對應(yīng)具體的二進(jìn)制為:10000010101010010111100。分析獲得的位置為:file_no=1,block_no=87228

 

我們將該塊dump出。

 

 

SQL> alter system dump datafile 1 block 87228;

System altered

 

 

row#0[7986] flag: K-----, lock: 0, len=46

col 0; len 30; (30):

 2f 31 32 30 66 34 37 30 38 5f 46 75 6c 6c 48 54 4d 4c 44 6f 63 75 6d 65 6e

 74 61 74 69 6f

col 1; len 4; (4): c3 04 39 24

tl: 8 fb: --H-FL-- lb: 0x0 cc: 1

col 0: [ 4] 00 41 59 3e

row#1[7940] flag: K-----, lock: 0, len=46

col 0; len 30; (30):

 2f 31 32 30 66 64 37 36 64 5f 4f 72 61 63 6c 65 44 61 74 61 62 61 73 65 4d

 65 74 61 44 61

col 1; len 4; (4): c3 02 50 1a

tl: 8 fb: --H-FL-- lb: 0x0 cc: 1

col 0: [ 4] 00 41 54 a1

row#2[7894] flag: K-----, lock: 0, len=46

col 0; len 30; (30):

 2f 31 32 30 66 64 37 36 64 5f 4f 72 61 63 6c 65 44 61 74 61 62 61 73 65 4d

 65 74 61 44 61

col 1; len 4; (4): c3 04 4c 1a

tl: 8 fb: --H-FL-- lb: 0x0 cc: 1

col 0: [ 4] 00 41 54 a2

 

 

上面標(biāo)紅的部分是我們看到了和Heap Index的差異,正式由于這部分信息的差異,才讓IOT Secondary Index體積略大。

 

從概念上,Secondary Index包括三部分葉子節(jié)點(diǎn)內(nèi)容:索引鍵值、logical rowid和對應(yīng)數(shù)據(jù)行的主鍵值。在進(jìn)行檢索的時(shí)候,Oracle首先用logical rowid進(jìn)行初步的試探,看看對應(yīng)的位置是否可以找到對應(yīng)數(shù)據(jù)。這個(gè)過程我們稱為physical guess。

 

如果找到了對應(yīng)數(shù)據(jù)行,那么皆大歡喜。如果沒有,oracle就只能通過數(shù)據(jù)行的主鍵值,進(jìn)行IOT索引樹定位。這個(gè)過程,要重復(fù)多讀一個(gè)段結(jié)構(gòu)。

 

具體Secondary Index的分析,留待下次進(jìn)行更加詳細(xì)的說明。

 

7、IOT的使用

 

我們已經(jīng)在一個(gè)系列中,詳細(xì)介紹了IOT的特性,最后我們聊一聊IOT應(yīng)用的場景??偟膩碚f,筆者認(rèn)為IOT在一般系統(tǒng)的應(yīng)用中,是沒有很廣泛的發(fā)揮場景的。在沒有明確的分析和POC實(shí)驗(yàn)基礎(chǔ)上,我們不要輕易進(jìn)行IOT決策。具體來說,有如下的幾點(diǎn):

 

ü IOT環(huán)境下,有更多的限制

 

我們常使用的堆表,雖然有各種問題,但是是目前我們可以得到的適應(yīng)性最廣,優(yōu)化策略最多的一種表存儲結(jié)構(gòu)。IOT則要受到很多的限制,例如:IOT必須要制定主鍵,也就是定義出核心訪問方式;PCTThreshold參數(shù)如果設(shè)置了,但是沒有指定overflew segment,那么超出閾值的數(shù)據(jù)行是不會被接受,要拋出異常。IOT表中分區(qū)和Lob類型不能同時(shí)使用。IOT維護(hù)工作要更多。

 

ü 單一讀取,讀多寫少的操作類型

 

我們定義出IOT后,實(shí)際上就是規(guī)定了數(shù)據(jù)表的核心訪問方式。當(dāng)我們使用主鍵條件時(shí),IOT可以方便的幫助我們定位記錄。但是其他查詢條件應(yīng)用secondary index的效率就是一個(gè)問題。而且secondary index也是不久前才支持的Oracle特性。如果我們的數(shù)據(jù)表應(yīng)用是一個(gè)多種檢索方式并存的操作表,那么IOT不是理想的選擇。

 

索引操作本身對增加、修改和刪除等DML操作是具有性能影響的。在IOT環(huán)境下,這種影響只會讓其更加劇烈。所以,如果數(shù)據(jù)表不是很少修改的數(shù)據(jù)表,那么使用IOT不是最好的選擇。

 

ü 主鍵列和列數(shù)目的約束

 

索引葉子節(jié)點(diǎn)中就能將所有數(shù)據(jù)行列保存在葉子節(jié)點(diǎn)上。而索引葉子節(jié)點(diǎn)是變化分裂頻繁的對象。所以,如果數(shù)據(jù)行列數(shù)很多,或者數(shù)據(jù)主鍵列相對很小,那么IOT的效果是不好的。

 

 

8、結(jié)論

 

Heap,IOTCluster是數(shù)據(jù)表的三大基本存儲類型。我們在實(shí)際中,要把握原則是:以堆表為核心,默認(rèn)都使用Heap Table。如果在架構(gòu)分析、性能測試和試運(yùn)行階段,發(fā)現(xiàn)性能問題,可以考慮使用IOT或者Cluster。但是,在選型的時(shí)候,一定要明確兩種表結(jié)構(gòu)的優(yōu)缺點(diǎn)和適用范圍。

 


網(wǎng)頁題目:簡述OracleIOT(IndexOrganizedTable)(下)
瀏覽地址:http://weahome.cn/article/iiijig.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部