Oracle 位图索引
內(nèi)容簡(jiǎn)介:
1.位圖索引
1.1位圖索引使用注意事項(xiàng);
1.2?使用位圖索引;
1.3?位圖索引對(duì)DML操作的影響;
2.位圖連接索引
2.1?明確需求后使用位圖索引;
2.1創(chuàng)建位圖連接索引的注意事項(xiàng):
?
1.位圖索引:
1.1位圖索引使用注意事項(xiàng):
? 一般適用于低基數(shù)列;
??適合數(shù)據(jù)倉(cāng)庫(kù);
??對(duì)于啟用位圖索引的表,應(yīng)盡量減少或避免DML操作;
??如果對(duì)一張含有多列位圖索引的表進(jìn)行大量DML操作,應(yīng)考慮將位圖索引刪除,DML操作結(jié)束后重建位圖索引;
??不適用于頻繁持續(xù)發(fā)生DML操作的OLTP系統(tǒng),會(huì)出現(xiàn)行鎖定,阻礙更新性能;
1.2?使用位圖索引
位圖索引與B-TREE索引有很大的不同,一個(gè)位圖索引由多個(gè)位串組成,每個(gè)位串都表示基礎(chǔ)列中一個(gè)獨(dú)立的有效值;每個(gè)位串是打開(kāi)或關(guān)閉,表示該值是否用于某一行;以人員信息表th03?為例,性別(gender)字段的值(男、女、未記錄),假如為其創(chuàng)建位圖索引,那么每個(gè)位串(男、女、未記錄)中的單個(gè)位表示一個(gè)給定行的值是男、女還是未記錄;當(dāng)判斷某一列是否適合創(chuàng)建位圖索引時(shí),需要考慮是否符合”低基數(shù)列”,根據(jù)應(yīng)用程序、數(shù)據(jù)組成以及數(shù)據(jù)庫(kù)中的表的情況不同,是否創(chuàng)建位圖索引的結(jié)論也可能不同;通常用來(lái)判斷的一條基本經(jīng)驗(yàn)法則是:”如果該列的有效值數(shù)目不足表中行數(shù)的1%,那么它就適合創(chuàng)建位圖索引,以th03來(lái)說(shuō),表行數(shù)為:500萬(wàn)行,而性別列的有效值數(shù)目?jī)H為3個(gè)(?男、女、未記錄),可以確定它適合創(chuàng)建位圖索引:
人員信息表(th03)
?
| 行 | ID | NAME | GENDER | IDCARD | HOMEADDR | JOBNO | BIRTHDATE |
| 1 | 998698 | 李天 | 男 | 440623197007253619 | 水晶洞1 | 526456 | 25-JUL-70 |
| 2 | 998699 | 李花 | 女 | 510802197007251223 | 水晶洞2 | 5785452 | 25-JUL-70 |
| 3 | 584625 | 李某 | 未記錄 | 564551545265642155 | 水晶洞3 | 1565452 | 01-JUL-88 |
?
SQL> create bitmap index ind_th03_gender on th03(gender) tablespace tbs03;
Index created.
Elapsed: 00:00:01.05
SQL> execute dbms_stats.gather_table_stats('sywu','th03',cascade=>true);
PL/SQL procedure successfully completed.
Elapsed: 00:00:04.31
SQL> @/oracle/getind
TABLE_NAME INDEX_NAME COLUMN_NAME? ?SIZE_GB INDEX_TY STATUS COMPRESS NUM_ROWS DISTINCT_KEYS
------------------------------ ------------------------------ ------------------------------ ---------- -------- -------- --------- ---------- -------- ---------- ----
TH03 IND_TH03_GENDER GENDER? ?.001953125?BITMAP VALID DISABLED 453?3
位圖索引的創(chuàng)建非??觳⑶艺加玫目臻g也非常小;位圖索引和B-TREE索引存儲(chǔ)值的方式不同,它存儲(chǔ)表中的每一行值(包括空值),對(duì)于B-TREE索引,單列索引不存儲(chǔ)空值,復(fù)合索引只要有一個(gè)非空值就可以存儲(chǔ);所以當(dāng)執(zhí)行?IS NULL?或者?IS NOT NULL?查詢時(shí)位圖索引的效率要高于B-TREE索引:
SQL> select count(*) from th03 where gender is null;
-----------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 5 | 1 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 5 | | |
| 2 | BITMAP CONVERSION COUNT | | 1 | 5 | 1 (0)| 00:00:01 |
|* 3 |?BITMAP INDEX SINGLE VALUE|?IND_TH03_GENDER?| | | | |
3 - access("GENDER" IS NULL)
Statistics
----------------------------------------------------------
1 recursive calls
0 db block gets
2 consistent gets
1 physical reads
如果在相同表相同列建立B-TREE索引,則該執(zhí)行必須全表掃描:
SQL> select count(*) from th03 where gender is null;
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 5 | 14908 (1)| 00:02:59 |
| 1 | SORT AGGREGATE | | 1 | 5 | | |
|* 2 |?TABLE ACCESS FULL|?TH03?| 1 | 5 | 14908 (1)| 00:02:59 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter("GENDER" IS NULL)
Statistics
----------------------------------------------------------
1 recursive calls
0 db block gets
54574 consistent gets
54562 physical reads
位圖索引還可以在另外一些情況使用,如使用聚合函數(shù):
SQL> select count(*),count(gender) from th03;
COUNT(*) COUNT(GENDER)
---------- -------------
5000000 5000000
-------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 5 | 203 (0)| 00:00:03 |
| 1 | SORT AGGREGATE | | 1 | 5 | | |
| 2 | BITMAP CONVERSION TO ROWIDS | | 5000K| 23M| 203 (0)| 00:00:03 |
| 3 |?BITMAP INDEX FAST FULL SCAN|?IND_TH03_GENDER?| | | | |
-------------------------------------------------------------------------------------------------
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
232 consistent gets
0 physical reads
如果你決定在應(yīng)用程序中實(shí)現(xiàn)位圖索引,應(yīng)時(shí)不時(shí)的檢查建立了位圖索引的列的數(shù)據(jù)組成,這一點(diǎn)很重要,如果你算錯(cuò)了包含位圖索引的任何列的基數(shù),可能會(huì)對(duì)應(yīng)用程序造成負(fù)面影響,如(位圖索引的存儲(chǔ)空間會(huì)增加、查詢性能會(huì)降低、重建索引的時(shí)間將增加);
1.3?位圖索引對(duì)DML操作的影響:
為了便于測(cè)試,我創(chuàng)建另一張分區(qū)表?th04,并為th04的性別、出生日期列創(chuàng)建位圖索引,最后向它插入100萬(wàn)行數(shù)據(jù):
SQL> create table th04
partition by range(id)(
partition th04_part1 values less than(1000000) tablespace tbs03,
partition th04_part2 values less than(2000000) tablespace tbs03,
partition th04_part3 values less than(3000000) tablespace tbs03,
partition th04_part4 values less than(4000000) tablespace tbs03,
partition th04_part5 values less than(5000000) tablespace tbs03,
partition th04_part6 values less than(maxvalue) tablespace tbs03
) as select * from tbbase where 1=0 ;
SQL> create bitmap index ind_th04_gender on th04(gender) local tablespace tbs03;
SQL> create bitmap index ind_th04_birthdate on th04(birthdate) local tablespace tbs03;
SQL>insert into th04 select * from tbbase where rownum<1000001;
1000000 rows created.
Elapsed: 00:00:40.24
從結(jié)果可以看出,插入100萬(wàn)行的數(shù)據(jù)花費(fèi)40秒,從表面上看花費(fèi)的時(shí)間似乎是合理的,但當(dāng)數(shù)據(jù)量不斷增加時(shí),特別對(duì)于一個(gè)數(shù)據(jù)倉(cāng)庫(kù)環(huán)境,一天處理幾百萬(wàn)甚至億行數(shù)據(jù)是司空見(jiàn)慣的,合理的情況應(yīng)考慮刪除位圖索引(如果是分區(qū)表則將目標(biāo)分區(qū)標(biāo)記為不可用),執(zhí)行完DML加載操作后重建位圖索引;
SQL> alter index IND_TH04_GENDER unusable;
SQL> alter index IND_TH04_BIRTHDATE unusable;
SQL> insert into th04 select * from tbbase where rownum<1000001;
禁用位圖索引后,插入100萬(wàn)行數(shù)據(jù)只花費(fèi)23?秒,對(duì)于大數(shù)據(jù)而言這或許可以提高裝載數(shù)據(jù)的性能;數(shù)據(jù)裝載結(jié)束后重建位圖索引:
SQL> alter index ind_th04_gender rebuild partition TH04_PART1;
alter index ind_th04_gender rebuild partition TH04_PART2;
alter index ind_th04_gender rebuild partition TH04_PART3;
alter index ind_th04_gender rebuild partition TH04_PART4;
alter index ind_th04_gender rebuild partition TH04_PART5;
alter index ind_th04_gender rebuild partition TH04_PART6;
alter index ind_th04_birthdate rebuild partition th04_part1;
.........
重建分區(qū)索引也可以通過(guò)下面的命令重建:
SQL> alter table th04 modify partition th04_part1 rebuild unusable local indexes;
此命令雖然簡(jiǎn)單,但它也有不足之處,對(duì)于一個(gè)指定的分區(qū),它只能按順序執(zhí)行;而對(duì)于每一個(gè)指令發(fā)出的命令重建分區(qū),它可以同時(shí)執(zhí)行多個(gè)語(yǔ)句,實(shí)現(xiàn)并行重建索引;
除裝載數(shù)據(jù)的影響外,位圖索引也會(huì)影響數(shù)據(jù)的DML操作,請(qǐng)觀察下面的人員信息表數(shù)據(jù):
人員信息表(th04)
?
| 行 | ID | NAME | GENDER | IDCARD | HOMEADDR | JOBNO | BIRTHDATE |
| 1 | 998698 | 李天 | 男 | 440623197007253619 | 水晶洞1 | 526456 | 25-JUL-70 |
| 2 | 998699 | 李四 | 男 | 510802197007251223 | 水晶洞2 | 5785452 | 25-JUL-70 |
| ..... | .... | ? | ? | ? | ? | ? | ? |
?
數(shù)據(jù)顯示他們的出生日期是相同的,并且出生日期列(BIRTHDATE)還建立了位圖索引(?IND_TH04_BIRTHDATE) ,因業(yè)務(wù)錯(cuò)誤記錄兩人的出生日期,so,現(xiàn)在對(duì)其修改:
---session 1-----
SQL> select distinct sid from v$mystat;
SID
----------
191
SQL> update th04 set birthdate='26-JUL-70' where idcard='440623197007253619';
1 row updated.
此時(shí)session 1?的用戶因?yàn)闃I(yè)務(wù)繁忙沒(méi)有及時(shí)提交,這時(shí)另一個(gè)業(yè)務(wù)員在新的會(huì)話?session2中修該另一個(gè)錯(cuò)誤記錄:
----session 2 -----
SQL> select distinct sid from v$mystat;
SID
----------
194
SQL> update th04 set birthdate='27-JUL-70' where idcard='510802197007251223';
session 2?中的用戶會(huì)一直處于等待狀態(tài),因?yàn)樗麄冃薷牡腻e(cuò)誤人員出生日期在更新之前在同一個(gè)位圖索引位串中,當(dāng)修改位串中的位信息時(shí)位串會(huì)被鎖定,直到更新提交后更新位串中的位值;觀察此時(shí)的鎖狀態(tài):
SQL>select sid,type,id1,id2,lmode,request,ctime,block from v$lock where sid in(191,194) order by sid
SID TY ID1 ID2 LMODE REQUEST CTIME BLOCK
---------- -- ---------- ---------- ---------- ---------- ---------- ----------
191 AE 100 0 4 0 2052 0
191 TM 75667 0 3 0 263 0
191 TX 65562 848 6 0 263 1
191 TM 75668 0 3 0 263 0
191 TO 65927 1 3 0 286 0
194 TM 75668 0 3 0 238 0
194 TX 131081 1071 6 0 238 0
194 TM 75667 0 3 0 238 0
194 TX 65562 848 0 4 238 0
194 AE 100 0 4 0 1406 0
對(duì)于session 1(191)此時(shí)持有一個(gè)6級(jí)事務(wù)鎖,并且堵塞session 2(194),它們請(qǐng)求的資源是一樣的,這并非巧合;只有當(dāng)session 1(191)提交或回退后,這個(gè)6級(jí)事物鎖才會(huì)被釋放,session 2(194)才能持有鎖修改數(shù)據(jù);
SID TY ID1 ID2 LMODE REQUEST CTIME BLOCK
---------- -- ---------- ---------- ---------- ---------- ---------- ----------
191 AE 100 0 4 0 2832 0
191 TO 65927 1 3 0 1066 0
194 TX 131081 1071 6 0 1018 0
194 TM 75667 0 3 0 1018 0
194 TM 75668 0 3 0 1018 0
194 AE 100 0 4 0 2186 0
所以建立位圖索引時(shí),應(yīng)仔細(xì)分析表結(jié)構(gòu)和表數(shù)據(jù),作出明智、合理選擇;以上測(cè)試因環(huán)境、版本、數(shù)據(jù)庫(kù)狀態(tài)測(cè)試結(jié)果可能不同;
?
轉(zhuǎn)載于:https://www.cnblogs.com/zwl715/p/3855990.html
總結(jié)
以上是生活随笔為你收集整理的Oracle 位图索引的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 日置BT3562无法开机怎么办,日常如何
- 下一篇: java源码导入eclipse_spri