索引組織表(Index Organizied Table)
索引組織表(index organized table, IOT)就是儲存在一個索引結構中的表。儲存在堆中的表是無組織的(也就是說,只要有可用的空間,資料可以放在任何地方),IOT中的資料則按主鍵儲存和排序。對你的應用來說,IOT表和一個“常規”表並無二致。
索引組織表的資料按主鍵排序手段被儲存在B-樹索引中,除了儲存主鍵列值外還儲存非鍵列的值。普通索引只儲存索引列,而索引組織表則儲存表的所有列的值。
索引組織表一般適應於靜態表,且查詢多以主鍵列。當表的大部分列當作主鍵列時,且表相對靜態,比較適合建立索引組織表!(8i以上)
既然它屬於表,那麼它當然也有建立索引的需求。由於它的索引的結構,比如說由於索引葉節點的分裂,行所在塊可能會發生改變,因而建立在IOT上的索引和一般的索引的最大區別是它存的是IOT的行的邏輯地址,也就是UROWID,oracle用這個邏輯rowid來猜這個行所在的塊,如果猜到了,那麼這個urowid是正確的,否則它從這個地址向下遍歷來找這條記錄。
IOT表的rowid是邏輯上的,因為IOT表中的行的位置是在不斷變化的(例如插入新的行,有可能帶來其它行的位置移動)
IOT有什麼意義呢?使用堆組織表時,我們必須為表和表主鍵上的索引分別留出空間。而IOT不存在主鍵的空間開銷,因為索引就是資料,資料就是索引,二者已經合二為一。但是,IOT帶來的好處並不止於節約了磁碟空間的佔用,更重要的是大幅度降低了I/O,減少了訪問緩衝區快取(儘管從緩衝區快取獲取資料比從硬碟讀要快得多,但緩衝區快取並不免費,而且也絕對不是廉價的。每個緩衝區快取獲取都需要緩衝區快取的多個閂,而閂是序列化裝置,會限制應用的擴充套件能力)
IOT適用的場合有:
1、完全由主鍵組成的表。這樣的表如果採用堆組織表,則表本身完全是多餘的開銷,因為所有的資料全部同樣也儲存在索引裡,此時,堆表是沒用的。
2、程式碼查詢表。如果你只會通過一個主鍵來訪問一個表,這個表就非常適合實現為IOT.
3、如果你想保證資料儲存在某個位置上,或者希望資料以某種特定的順序物理儲存,IOT就是一種合適的結構。
IOT提供如下的好處:
·提高緩衝區快取效率,因為給定查詢在快取中需要的塊更少。
·減少緩衝區快取訪問,這會改善可擴縮性。
·獲取資料的工作總量更少,因為獲取資料更快。
·每個查詢完成的物理I/O更少,因為對於任何給定的查詢,需要的塊更少,而且對地址記錄的一個物理 I/O 很可能可以獲取所有地址(而不只是其中一個地址,但堆表實現就只是獲取一個地址)
如果經常在一個主鍵或惟一鍵上使用BETWEEN 查詢也是如此,因為相近的記錄存在一起,查詢時引入的邏輯IO和物理IO都會更少。
索引組織表的詳細引數
ops$tkyte@ORA10GR1> select dbms_metadata.get_ddl( 'TABLE', 'T1' ) from dual;
S_METADATA.GET_DDL('TABLE','T1')
-----------------------------------------------------------------------------
CREATE TABLE "OPS$TKYTE"."T1"
"X" NUMBER(*,0),
"Y" VARCHAR2(25),
"Z" DATE,
PRIMARY KEY ("X") ENABLE
ANIZATION INDEX
OMPRESS
PCTFREE 10 INITRANS 2 MAXTRANS 255 LOGGING
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "USERS"
PCTTHRESHOLD 50
NOCOMPRESS 選項
這個選項對索引一般都可用。它告訴 Oracle 把每個值分別儲存在各個索引條目中(也就是不壓縮)。如果物件的主鍵在 A、B 和 C 列上, A、B 和 C 的每一次出現都會物理地儲存。 NOCOMPRESS 反過來就是 COMPRESS N ,在此 N 是一個整數,表示要壓縮的列數。這樣可以避免重複值,並在塊級提取 “公因子”( factor out )。這樣在 A 的值(以及 B 的值)重複出現時,將不再物理地儲存它們。
下面做一個快速的測試,對前面 CREATE TABLE 的 SELECT 分別採用 NOCOMPRESS 、 COMPRESS 1 和COMPRESS 2 選項,來展示能節省多少空間。先來建立 IOT ,但不進行壓縮:
ops$tkyte@ORA10GR1> create table iot
2 ( owner, object_type, object_name,
3 constraint iot_pk primary key(owner,object_type,object_name)
4 )
5 organization index
6 NOCOMPRESS
7 as
8 select distinct owner, object_type, object_name
9 from all_objects
10 /
tablle created.
現在可以測量所用的空間。為此我們將使用 ANALYZE INDEX VALIDATE STRUCTURE 命令。這個命令會填寫一個名為 INDEX_STATS 的動態效能檢視,其中最多隻包含一行,即這個 ANALYZE 命令最後一次執行的資訊:
ops$tkyte@ORA10GR1> analyze index iot_pk validate structure;
index analyzed.
ops$tkyte@ORA10GR1> select lf_blks, br_blks, used_space,
2 opt_cmpr_count, opt_cmpr_pctsave
3 from index_stats;
LF_BLKS BR_BLKS USED_SPACE OPT_CMPR_COUNT OPT_CMPR_PCTSAVE
284 3 2037248 2 33
由此顯示出,我們的索引目前使用了 284 個葉子塊(即資料所在的塊),並使用了 3 個分支塊( Oracle在索引結構中導航所用的塊)來找到這些葉子塊。使用的空間大約是 2MB (2,038,248 位元組)。另外兩列名字有些奇怪,這兩列是要告訴我們一些資訊。 OPT_CMPR_COUNT (最優壓縮數)列要說的是:“ 如果你把這個索引置為 COMPRESS 2 ,就會得到最佳的壓縮 ” 。 OPT_CMPR_PCTSAVE (最優的節省壓縮百分比)則是說 ,如果執行 COMPRESS 2 ,就能節省大約 1/3 的儲存空間,索引只會使用現在 2 /3 的磁碟空間。
下面用COMPRESS 2進行壓縮:
ops$tkyte@ORA10GR1> alter table iot move compress 2;
Table altered.
ops$tkyte@ORA10GR1> analyze index iot_pk validate structure;
Index analyzed.
ops$tkyte@ORA10GR1> select lf_blks, br_blks, used_space,
2 opt_cmpr_count, opt_cmpr_pctsave
3 from index_stats;
LF_BLKS BR_BLKS USED_SPACE OPT_CMPR_COUNT OPT_CMPR_PCTSAVE
190 1 1359357 2 0
現在大小有了顯著減少,不論是葉子塊數還是總的使用空間都大幅下降。
OVERFLOW&PCTTHRESHOLD&INCLUDING選項
OVERFLOW 子句允許你建立另一個段(這就使得 IOT 成為一個多段物件,就像有一個 CLOB 列一樣),如果 IOT 的行資料變得太大,就可以溢位到這個段中。
注意:構成主鍵的列不能溢位,它們必須直接放在葉子塊上。
PCTTHRESHOLD :行中的資料量超過塊的這個百分比時,行中餘下的列將儲存在溢位段中。所以,如果 PCTTHRESHOLD 是 10% ,而塊大小是 8KB ,長度大於 800 位元組的行就會把其中一部分儲存在別處,而不能在索引塊上儲存。
INCLUDING :行中從第一列直到 INCLUDING 子句所指定列(也包括這一列)的所有列都儲存在索引塊上,餘下的列儲存在溢位段中。
對於 IOT 最後要考慮的是建立索引。 IOT 本身可以有一個索引,就像在索引之上再加索引,這稱為二次索引( secondary index )。 正常情況下,索引包含了所指向的行的實體地址,即 rowid 。而 IOT 二次索引無法做到這一點;它必須使用另外某種方法來指示行的地址。這是因為 IOT 中 的行可以大量移動, 而且它不像堆組織表中的行那樣 “ 遷移 ” 。 IOT 中的行肯定在索引結構中的每個位置上,這取決於它的主鍵值;只有當索引本身的大小和形狀 發生改變時行才會移動。
為了適應這種情況, Oracle 引入了一個邏輯 rowid ( logical rowid )。 這些邏輯 rowid 根據 IOT 主鍵建立。對於行的當前位置還可以包含一個 “ 猜測 ” ,不過這個猜測幾乎是錯的,因為稍過一段時間後, IOT中的資料可能就會 移動。這個猜測是行第一次置於二次索引結構中時在 IOT 中的實體地址。如果 IOT 中 的行必須移動到另外一個塊上,二次索引中的猜測就會變得 “ 過時 ” 。因 此,與常規表相比, IOT 上的索 引效率稍低。在一個常規表上,索引訪問通常需要完成一個 I/O 來掃描索引結構,然後需要一個讀來讀取表資料。對於 IOT , 通常要 完成兩個掃描;一次掃描二次結構,另一次掃描 IOT 本身。除此之外, IOT 上的索引可以使用非主鍵列提供 IOT 資料的快速、高效訪問。
索引組織表小結
在 建立 IOT 時,最關鍵的是適當地分配資料,即哪些資料儲存在索引塊上,哪些資料儲存在溢位段上。對溢位條件不同的各種場景進行基準測試,檢視對 INSERT 、 UPDATE 、 DELETE 和 SELECT 分別有怎樣的影響。如果結構只建立一次,而且要頻繁讀取,就應該儘可能地把資料放在索引塊上(最合適獲取),要麼頻繁地組織索引中的資料(不適於修改)。堆表的 freelist 相關考慮對 IOT 也同樣適用。 PCTFREE 和PCTUSED 在 IOT 中 是兩個重要的角色。不過, PCTFREE 對於 IOT 不像對於堆表那麼重要,另外 PC TUSED 一般不起作用。不過,考慮 OVERFLOW 段時, PCTFREE 和 PCTUSED 對於 IOT 的意義將與對於堆表一樣重大;要採用與堆表相同的邏輯為溢位段設定這兩個引數。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/24104518/viewspace-712382/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 索引組織表(index organized table ,IOT)索引IndexZed
- Oracle堆組織表的索引和索引組織表Oracle索引
- oracle 索引組織表Oracle索引
- Oracle 索引組織表(IOT)Oracle索引
- 索引組織表上建立BITMAP索引(三)索引
- 索引組織表上建立BITMAP索引(二)索引
- 索引組織表上建立BITMAP索引(一)索引
- ORACLE索引組織表討論Oracle索引
- oracle iot索引組織表(一)Oracle索引
- oracle iot索引組織表(二)Oracle索引
- 資料庫表,索引(索引組織表,聚簇表,聚簇索引,)資料庫索引
- 在OLTP系統使用索引組織表IOT索引
- (轉)索引掃描還是全表掃描(Index Scan Or Full Table Scan)索引Index
- 轉)索引掃描還是全表掃描(Index Scan Or Full Table Scan)索引Index
- Oracle表table與索引index的分析及索引重建及統計資訊匯入匯出Oracle索引Index
- SQL Server 重新組織生成索引SQLServer索引
- 資料庫表--index organized table資料庫IndexZed
- 資料庫表--index clustered table資料庫Index
- [20151008]索引組織表上建立BITMAP索引.txt索引
- 查詢使用表空間的TABLE,INDEX,INDEX SUBPARTITIONIndex
- table/index/LOBINDEX遷移表空間Index
- Oracle 堆組織表(HOT)Oracle
- 如何更改table及index的表空間Index
- 表、索引遷移表空間alter table move索引
- index table (IOT)Index
- index索引Index索引
- 【oracle 效能優化】組合索引之index_ssOracle優化索引Index
- partition table and partition indexIndex
- TABLE size (including table,index,lob,lobindex)Index
- 分割槽索引之本地(local index)索引和全域性索引(global index)索引Index
- update表中index索引列對原索引條目做什麼操作?Index索引
- alter table using indexIndex
- table表頭分組程式碼例項
- index_oracle索引梳理系列及分割槽表梳理IndexOracle索引
- Elasticsearch之索引模板index template與索引別名index aliasElasticsearch索引Index
- 【BUG】當使用TTS(傳輸表空間時)從其他平臺到HP可造成索引組織表損壞TTS索引
- Mysql——index(索引)使用MySqlIndex索引
- oracle index索引原理OracleIndex索引