深入探討Oracle函數(shù)索引
Oracle還是比較常用的,于是我研究了一下Oracle函數(shù)索引,在這里拿出來(lái)和大家分享一下,希望對(duì)大家有用。
1.Oracle函數(shù)索引的好處: Exp: function(column1) 如果表中有1000行,即便column1列上建有索引,索引在此時(shí)也不被使用,function會(huì)執(zhí)行1000次。
2.建立Oracle函數(shù)索引會(huì)使插入/更新性能稍有下降,但是查詢速度有了極大的提高。另外如果更新的時(shí)候沒有涉及到建立Oracle函數(shù)索引的這個(gè)列,那就不會(huì)產(chǎn)生額外的開銷。
3.部分行建立索引:
1)某一列只有很少的基數(shù),例如只有Y和N
2)通常只會(huì)查詢where column1 = ‘N’
3)并且值為N的行占很小的比例
4)在此列上建立索引,由于很大的一部分索引空間是浪費(fèi)的(等于Y的),不會(huì)使用到的,所以我們可以在值為’N’的那些行上面建立索引。
5)Create index I on T(decode(column1 , ‘N’, ‘N’))
6)利用的是B樹索引特性,如果列值為null,在索引中就沒有相應(yīng)的條目。
4.使用Oracle函數(shù)索引來(lái)保證復(fù)雜的約束:(某個(gè)條件成立時(shí),X,Y,Z必須唯一)
1)如果項(xiàng)目表,項(xiàng)目有2種狀態(tài),ACTIVE和INACTIVE
2)希望ACTIVE的項(xiàng)目必須有唯一的項(xiàng)目名,INACTIVE的項(xiàng)目沒有此要求
3)此時(shí)項(xiàng)目狀態(tài)這列上我們不適合建立唯一鍵
4)但是我們可以建立一個(gè)唯一索引
5)Create unique index I on T(decode(STATUS , ‘ACTIVE’ , NAME))
6)利用的還是B樹索引特性,如果列值為null,在索引中就沒有相應(yīng)的條目。
Oracle函數(shù)索引索引的一些常見問(wèn)題
1.B樹索引特性,如果列值為null,在索引中就沒有相應(yīng)的條目。
1)Create table T (x int , y int)
2)Create unique index I T(x , y)
3)Insert into T values(1 , 1)
4)Insert into T values(null , 1)
5)Insert into T values(1 , null)
6)Insert into T values(null , null)
7)此時(shí)索引中只有三行.(null , null)不在索引行中
8)Insert into T values(null , null) --成功插入
9)Insert into T values(1 , null)--報(bào)錯(cuò),違反index唯一性
10) 所以我們可以看到ORACLE中null <> null (null代表N/A)
11) Where x is null --這個(gè)查詢無(wú)法使用索引,因?yàn)椋╪ull,null)不在索引中,如果ORACLE使用索引就會(huì)得到錯(cuò)誤的答案
12) 同樣能夠得出結(jié)論,如果在一個(gè)允許null的列上面建立索引,x is null也不會(huì)使用索引
13) 可以使用索引的條件Create table T (x int , y int not null);
2.外鍵建立索引是需要的
3.索引跳躍式掃描
1)Create index I T(x , y)
2)Select * from T where x=5; --此時(shí)優(yōu)化器可能不會(huì)使用索引
3)Select x , y from T where x=5;--可能使用索引,因?yàn)樗枰膬?nèi)容都在索引中
4)索引跳躍式掃描—skip scan
5)如果y只有2個(gè)基數(shù),Y和N ,oracle會(huì)采用index
6)Select * from T where x=5; --會(huì)經(jīng)過(guò)如下處理
7)Select * from T where x=5 and y=’Y’
8)Union all
9)Select * from T where x=5 and y=’N’;
4.如果索引建立在一個(gè)允許null的列上面, select * from T就會(huì)使用全表掃描,不使用索引,因?yàn)閚ull的行并不在索引行中,所以不會(huì)使用index統(tǒng)計(jì)數(shù)目。
5.select * from T where x=5 等價(jià)于select * from T where to_number(x)=’5’,由于存在隱式轉(zhuǎn)換,所以x上的索引不會(huì)得到使用
6.where trunc(date) = trunk(sysdate) 可以轉(zhuǎn)換成 date >=trunc(sysdate) and date<trunk(sysdate+1)
7.定期分析表:如果發(fā)現(xiàn)Oracle 在有索引的情況下,沒有使用索引,這并不是Oracle 的優(yōu)化器出錯(cuò)。在有些情況下,Oracle 確實(shí)會(huì)選擇全表掃描(Full Table Scan),而非索引掃描(Index Scan)。
8.有些情況下單列索引不如復(fù)合索引有效率!以上介紹Oracle函數(shù)索引。
【編輯推薦】