1. 程式人生 > >oracle 常用索引分析和註意事項

oracle 常用索引分析和註意事項

相關操作 rac 什麽是 效率 rom table 圖片 位圖索引 地址

參考:

https://www.cnblogs.com/wishyouhappy/p/3681771.html

https://blog.csdn.net/weivi001/article/details/45498405

1.什麽是索引

索引(index)是數據庫對象的一種。索引的關鍵在於通過一組排序後的物理地址作為鍵來取代默認的全表掃描檢索方式,就像為書本添加目錄,通過犧牲物理內存的方式提高數據的檢索效率。

它對用戶時透明的,它的創建不會影響對表的sql操作。索引一旦建立,在表上進行DML操作時(例如在執行插入、修改或者刪除相關操作時),oracle會自動管理索引。

oracle創建主鍵時會自動創建索引

2.對索引的增刪改查操作

1.創建默認索引

CREATE UNIQUE INDEX (索引名稱) ON 表名 (列名1,列名2...) ; --unique(默認)表示唯一索引

2.修改索引

alter index (舊索引名稱) rename to(新索引名稱);

3.刪除索引

drop index (索引名稱);

4.查看索引

查看某表的所有索引:

select index_name,index-type, tablespace_name, uniqueness from all_indexes where table_name =(表名);

3.索引的主要分類及適用場景

1.b樹索引(默認索引,保存排序過的索引列和對應的rowid值)

b樹索引是oracle最常見的的索引,它的原理是利用了b-樹的數據結構(b樹的原理:https://blog.csdn.net/baidu_30569267/article/details/80983295)

b樹索引結構圖:

技術分享圖片

b樹的所有葉子節點擁有相同的深度,oracle將索引列和對應的rowid值存入葉子節點上,因此所有的檢索速度基本都是相同的。

b樹索引的不適用場景:

不適合鍵值較少的列(重復數據較多的列)

假如索引列TYPE有5個鍵值,如果有1萬條數據,那麽 WHERE TYPE = 1將訪問表中的2000個數據塊。再加上訪問索引塊,一共要訪問大於200個的數據塊。

如果全表掃描,假設10條數據一個數據塊,那麽只需訪問1000個數據塊,既然全表掃描訪問的數據塊少一點,肯定不會利用b樹索引了。

(不過,事實上,當取出的行數據占用表中大部分的數據時,即使添加了B樹索引,數據庫如oracle、mysql也不會使用B樹索引,很有可能還是一行行全部掃描)

2.位圖索引(bit-map index)

位圖索引是對列的每個鍵值設置一個位圖。

比如有這樣一列a:

10 20 30 20 10 30 10 30 20 30

那麽會建立三個位圖,如下:

KEY=10 1 0 0 0 1 0 1 0 0 0
KEY=20 0 1 0 1 1 0 0 0 1 0
KEY=30 0 0 1 0 0 1 0 1 0 1

這適合於該列的基數非常小的情況,當建立位圖索引時,會為每個獨立的值建立向量,比如上面3個,就會建立3個向量:key=10: 1000101000,key=20: 0101100010...

如果再有一列b:

x y x x y y y x y

key = x : 1 0 1 1 0 0 0 1 0

key = y : 0 1 0 0 1 1 1 0 1

如果你對a列和b列使用 and 或者 or操作,這裏就會體現位圖索引使用bit的優勢:比如 "a=10 and b =x " :它會將 key=10 :100010100向量 和 b=x :101100010向量進行與操作,更快的取出索引對應的行

適用場景:

和B樹索引相反,位圖索引適合鍵值重復率高的表,若重復值很低,則位圖索引相對的會需要大量數據。由於位圖索引采用0,1記錄某行是否包含該鍵值,因此非常適合AND, OR, NOT,count等這樣的邏輯操作。
位圖索引非常不適合有大量“寫”的操作,因為每一個位圖鍵值中,都可能對於多條記錄,當修改一條記錄更新位圖鍵值時,會在對應的位圖索引鍵上加鎖,從而導致對其它記錄的修改也會被阻塞。

4.索引的建立原則

1. 如果有兩個或者以上的索引,其中有一個唯一性索引,而其他是非唯一,這種情況下oracle將使用唯一性索引而完全忽略非唯一性索引

2. 至少要包含組合索引的第一列(即如果索引建立在多個列上,只有它的第一個列被where子句引用時,優化器才會使用該索引),因此最常查詢的列應該放在前面

3.小表不需要建立索引

4.列中有很多空值,但經常查詢該列上非空記錄時應該建立索引

5.經常進行連接查詢的列應該創建索引

6. LONG(可變長字符串數據,最長2G)和LONG RAW(可變長二進制數據,最長2G)列不能創建索引

7.通常來說,表的索引越多,其查詢的速度也就越快。但是,表的更新速度則會降低。這主要是因為,在更新記錄的同時需要更新相關的索引信息。為此,需要在這個更新速度與查詢速度之間取得一個均衡點。同時過多的索引會增加物理內存,數據庫管理員需要定期去優化索引。

5.無法使用索引的情況

1.通配符在搜索詞首出現時不能用索引:

--下面的方式oracle不適用name索引

select * from student where name like ‘%wish%‘;

--如果通配符出現在字符串的其他位置時,優化器能夠利用索引;如下:

select * from student where name like ‘wish%‘;

2.不要在查詢條件中使用not:

select * from student where not (score=100);

select * from student where score <> 100;

--替換為 select * from student where score>100 or score <100

3. b樹索引上使用空值比較將停止使用索引,Oracle的索引不保存全部為空的行:

select * from student where score is not null;

select * from student where score is null;

有一個可以變通的方法,即我們在創建表的時候,為每個列都指定為非空約束(NOT NULL),並且在必要的列上使用default值


oracle 常用索引分析和註意事項