索引組織表上建立BITMAP索引(二)
Oracle的索引組織表也支援BITMAP索引型別,不過需要對映表的支援。
描述一下對映表的結構的特點。
索引組織表上建立BITMAP索引(一):http://yangtingkun.itpub.net/post/468/503513
上一篇文章介紹了索引組織表的對映表,下面簡單描述一下對映表的結構,以及為什麼Oracle需要這個對映表。
SQL> DROP TABLE T_INDEX_ORG;
表已刪除。
SQL> CREATE TABLE T_INDEX_ORG
2 (ID NUMBER PRIMARY KEY,
3 NAME VARCHAR2(30),
4 TYPE VARCHAR2(30))
5 ORGANIZATION INDEX
6 MAPPING TABLE;
表已建立。
SQL> CREATE BITMAP INDEX IND_B_INDEX_TYPE
2 ON T_INDEX_ORG (TYPE);
索引已建立。
SQL> SELECT TABLE_NAME, IOT_NAME, IOT_TYPE
2 FROM USER_TABLES
3 WHERE IOT_TYPE IS NOT NULL;
TABLE_NAME IOT_NAME IOT_TYPE
------------------------------ ------------------------------ ------------
SYS_IOT_MAP_32399 T_INDEX_ORG IOT_MAPPING
T_INDEX_ORG IOT
SQL> SELECT TABLE_NAME, INDEX_NAME, INDEX_TYPE
2 FROM USER_INDEXES
3 WHERE TABLE_NAME = 'T_INDEX_ORG';
TABLE_NAME INDEX_NAME INDEX_TYPE
------------------------------ ------------------------------ -------------
T_INDEX_ORG SYS_IOT_TOP_32399 IOT - TOP
T_INDEX_ORG IND_B_INDEX_TYPE BITMAP
現在已經建立好索引組織表、對映表和BITMAP索引,首先來看看對映表的結構:
SQL> DESC SYS_IOT_MAP_32399
名稱 是否為空? 型別
----------------------------------------------------------------- -------- --------------
SYS_NC_01 ROWID
對映表的結構很簡單,只有一個ROWID欄位。
下面在表中插入一條記錄:
SQL> INSERT INTO T_INDEX_ORG VALUES (1, 'T_INDEX_ORG', 'IOT');
已建立 1 行。
可以看到,對映表中自動包含了ROWID資訊。
SQL> SELECT * FROM SYS_IOT_MAP_32399;
SYS_NC_01
--------------------------------------------------
*BAAAAAACwQL+
根據這個ROWID,就可以從索引組織表找到對應的記錄:
SQL> SELECT * FROM T_INDEX_ORG
2 WHERE ROWID = '*BAAAAAACwQL+';
ID NAME TYPE
---------- ------------------------------ ------------
1 T_INDEX_ORG IOT
但是仔細觀察一下,就會發現對映表中的ROWID與從索引組織表中查詢得到的ROWID並不相同:
SQL> SELECT ROWID FROM T_INDEX_ORG;
ROWID
-------------------------------------
*BAJAADQCwQL+
透過DUMP看看二者的差別:
SQL> COL D_ROWID FORMAT A50
SQL> SELECT ROWID, DUMP(ROWID, 16) D_ROWID
2 FROM T_INDEX_ORG;
ROWID D_ROWID
------------------------------- ------------------------------------------------
*BAJAADQCwQL+ Typ=208 Len=10: 2,4,2,40,0,34,2,c1,2,fe
SQL> COL SYS_NC_01 FORMAT A30
SQL> SELECT SYS_NC_01, DUMP(SYS_NC_01, 16) D_ROWID
2 FROM SYS_IOT_MAP_32399;
SYS_NC_01 D_ROWID
------------------------------ --------------------------------------------------
*BAAAAAACwQL+ Typ=208 Len=10: 2,4,0,0,0,0,2,c1,2,fe
原來索引組織表的ROWID包括物理猜資訊,而對映表儲存的ROWID,沒有記錄實體地址資訊,而只包括了索引組織表的主鍵。
那麼索引組織表就有一個有趣的特性,可以透過多個ROWID訪問相同的一條記錄:
SQL> SELECT * FROM T_INDEX_ORG
2 WHERE ROWID = '*BAJAADQCwQL+';
ID NAME TYPE
---------- ------------------------------ ------------------------------
1 T_INDEX_ORG IOT
SQL> SELECT * FROM T_INDEX_ORG
2 WHERE ROWID = '*BAAAAAACwQL+';
ID NAME TYPE
---------- ------------------------------ ------------------------------
1 T_INDEX_ORG IOT
SQL> SELECT * FROM T_INDEX_ORG
2 WHERE ROWID = '*BABCDAACwQL+';
ID NAME TYPE
---------- ------------------------------ ------------------------------
1 T_INDEX_ORG IOT
SQL> SELECT * FROM T_INDEX_ORG
2 WHERE ROWID = '*BADDDDACwQL+';
ID NAME TYPE
---------- ------------------------------ ------------------------------
1 T_INDEX_ORG IOT
換句話說,只要ROWID包含的主鍵資訊是正確的,就可以訪問到對應的記錄,而與邏輯ROWID中的實體地址是否存在、是否準確無關。
可以看到,前面兩個ROWID分別是索引組織表真實的ROWID,以及對映表中儲存的ROWID,但是後面兩個ROWID,完全是根據ROWID的規則仿寫的,而且居然也可以得到記錄。
扯遠一點,這一點就是邏輯ROWID和物理ROWID的一個重要區別。一條記錄只有一個物理ROWID,而一個物理ROWID是在資料庫中唯一的,它表示唯一一個實體地址,它可能對應到一條記錄,也可能不對應任何一條記錄。
而根據上面的結果也可以看到,多個邏輯ROWID可以指向同一條記錄,也就是說1條記錄對應多個邏輯ROWID。
而一個邏輯ROWID也可以指向多條記錄,看一個簡單的例子:
SQL> CREATE TABLE T_INDEX_ORG1
2 (ID NUMBER PRIMARY KEY)
3 ORGANIZATION INDEX;
表已建立。
SQL> INSERT INTO T_INDEX_ORG1 VALUES (1);
已建立 1 行。
SQL> SELECT ROWID FROM T_INDEX_ORG1;
ROWID
-----------------------------------------
*BAJABSwCwQL+
SQL> ALTER TABLE T_INDEX_ORG1 MOVE MAPPING TABLE;
表已更改。
SQL> SELECT TABLE_NAME, IOT_NAME, IOT_TYPE
2 FROM USER_TABLES
3 WHERE IOT_TYPE IS NOT NULL;
TABLE_NAME IOT_NAME IOT_TYPE
------------------------------ ------------------------------ ------------
SYS_IOT_MAP_32399 T_INDEX_ORG IOT_MAPPING
SYS_IOT_MAP_32427 T_INDEX_ORG1 IOT_MAPPING
T_INDEX_ORG IOT
T_INDEX_ORG1 IOT
SQL> SELECT * FROM SYS_IOT_MAP_32427;
SYS_NC_01
------------------------------
*BAAAAAACwQL+
SQL> SELECT * FROM T_INDEX_ORG
2 WHERE ROWID = '*BAAAAAACwQL+';
ID NAME TYPE
---------- ------------------------------ ------------------------------
1 T_INDEX_ORG IOT
SQL> SELECT * FROM T_INDEX_ORG1
2 WHERE ROWID = '*BAAAAAACwQL+';
ID
----------
1
同一個邏輯ROWID可以指向不同表中的不同記錄,只要它們的主鍵資訊是相同的。
於是可以看到一個十分有趣的SQL:
SQL> SELECT A.ROWID, B.ROWID
2 FROM T_INDEX_ORG A, T_INDEX_ORG1 B
3 WHERE A.ROWID = B.ROWID;
ROWID ROWID
----------------------------------------- ------------------------------------
*BAJAADQCwQL+ *BAJABUwCwQL+
兩個ROWID明明不等,但是居然可以查詢出結果。這就是邏輯ROWID特點所造成的。
這次扯的真是有點遠了,還是回到最初的話題。
可以看到,對於建立了對映表的索引組織表,在做任何修改的時候,都會同步修改對映表中的ROWID資訊。而如果是透過ALTER TABLE MOVE MAPPING TABLE新增的對映表,會自動將目前索引組織表中所有記錄的ROWID,新增到對映表中。
SQL> SELECT * FROM T_INDEX_ORG;
ID NAME TYPE
---------- ------------------------------ --------------------
1 T_INDEX_ORG IOT
SQL> SELECT * FROM SYS_IOT_MAP_32399;
SYS_NC_01
------------------------------
*BAAAAAACwQL+
SQL> UPDATE T_INDEX_ORG SET ID = 2;
已更新 1 行。
SQL> SELECT * FROM SYS_IOT_MAP_32399;
SYS_NC_01
------------------------------
*BAJAADQCwQP+
當記錄的主鍵發生變化的時候,Oracle也會更新對映表中儲存的邏輯ROWID資訊。
在Oracle確保對映表和索引組織表的同步的情況下,就可以利用對映表來建立BITMAP索引了。
Oracle之所以無法直接在索引組織表上建立BITMAP索引,是因為BITMAP索引儲存的是一個個ROWID範圍,在這些範圍內透過BITMAP來對應表的ROWID資訊。而索引組織表的實際儲存格式是索引,而索引的根節點、分支節點和葉節點都儲存在一起,因此實際儲存表資料的葉節點在一個EXTENT中是不連續的。
建立了對映表後,BITMAP索引實際是建立在對映表這個堆表上,透過對映表中儲存的邏輯ROWID資訊,對應到索引組織表中。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4227/viewspace-670807/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 索引組織表上建立BITMAP索引(三)索引
- 索引組織表上建立BITMAP索引(一)索引
- [20151008]索引組織表上建立BITMAP索引.txt索引
- oracle iot索引組織表(二)Oracle索引
- Oracle堆組織表的索引和索引組織表Oracle索引
- oracle 索引組織表Oracle索引
- Oracle 索引組織表(IOT)Oracle索引
- 資料庫表,索引(索引組織表,聚簇表,聚簇索引,)資料庫索引
- 索引組織表(Index Organizied Table)索引Index
- ORACLE索引組織表討論Oracle索引
- oracle iot索引組織表(一)Oracle索引
- 索引組織表(index organized table ,IOT)索引IndexZed
- 在OLTP系統使用索引組織表IOT索引
- 物化檢視上使用bitmap索引索引
- 索引與null(二):組合索引索引Null
- SQL Server 重新組織生成索引SQLServer索引
- 點陣圖索引(Bitmap Index)——索引共用索引Index
- [轉]:bitmap索引和B*tree索引分析索引
- BITMAP索引的INLIST ITERATOR與BITMAP OR索引
- BITMAP索引異常增大索引
- 分割槽表的bitmap索引不能是global的索引
- DB2_建立重組索引DB2索引
- Oracle大表快速建立索引Oracle索引
- 點陣圖索引(Bitmap Index)——從B*樹索引到點陣圖索引索引Index
- 分割槽表並行建立索引並行索引
- Oracle 找出需要建立索引的表Oracle索引
- [20120324]IOT索引組織表相關資訊的學習(二).txt索引
- oracle 點陣圖索引(bitmap index)Oracle索引Index
- 點陣圖索引:原理(BitMap index)索引Index
- 點陣圖索引(bitmap-index)索引Index
- 【索引】Bitmap點陣圖索引與普通的B-Tree索引鎖的比較索引
- mysql組合索引,abc索引命中MySql索引
- 【Bitmap Index】B-Tree索引與Bitmap點陣圖索引的鎖代價比較研究Index索引
- mongodb建立索引和刪除索引和背景索引backgroundMongoDB索引
- ElasticSearch建立索引Elasticsearch索引
- DocumentDB 建立索引索引
- bitmap index點陣圖索引系列(一)Index索引
- lucene(二) 索引的建立、增刪改查索引