Oracle索引之Btree索引

2021-09-14 04:42:27 字數 2442 閱讀 8681

日常開發中,對於資料的查詢如果需要優化,常聽說要加個索引。但是為什麼加了索引,資料的查詢就快了呢?那是不是加了索引就一定會是有效或者有利的呢?

oracle中常見有btree索引,位圖索引和函式索引。

我們今天就先介紹一下這個btree索引吧。既然叫btree索引,那就從它的樹結構說起:

建btree索引其實是先拿出所有資料排序,將有序的索引列的值和rowid存進oracle的各個資料塊中,形成索引塊,存在記憶體中。這些資料塊以樹結構的形式組織起來,父節點只記錄子節點的鍵值位置資訊,不存具體資料,所以,只有葉子塊存具體資料(索引列資料和rowid)。其他非葉子節點只記錄位置資訊,占用空間非常小,所以索引塊即使存了很多資料,這顆樹的高度其實並不高。如下圖:

查詢的時候,根據樹的結構去查詢,產生的邏輯讀的次數也就是樹的高度,走索引的邏輯讀不會很多,產生的io少,所以肯定比全表掃瞄要效率高。

注意:如果索引列包含空值,是不會走索引的。所以,在一些查詢中,要想走索引,需要加上條件「索引列 is not null」或者修改表字段屬性為非空。

例如:沒建索引之前,對於統計函式肯定是全表掃瞄:

建索引之後,如果我們不對空值進行篩選,是不走索引的:

對於空值進行排除後,可以看到走索引了:

在最大最小值的查詢中,索引也是優化的乙個手段。沒建索引之前:

建了索引之後,因為索引的有序特性,直接去索引樹的最右或最左葉子節點找一遍就可以了:

再看select具體欄位和select *的區別。

比較下面兩個查詢:

上面我們說過,索引儲存了索引列和rowid的資料,如果我們只取索引列的資料,則,訪問到索引塊即取到我們需要的資料了,如果還需要取其他欄位的資料,在索引中找不到,則會存在乙個去表中取資料的操作,即「table access by index rowid 」,多產生的讀取操作必然會增加消耗,所以如果有些字段必須展現,又資料量很小,可以考慮建聯合索引。

既然索引是有序的,那我們的order by操作是不是也可以用索引來優化呢?答案是肯定的:

建完索引之後:

可見走索引的排序要比全表掃瞄的排序消耗小很多。

上面我們見到了執行計畫中各種走索引的方式,那他們有什麼區別呢?感興趣的童鞋可以討論討論呀~

上面說到,為了避免回表,我們可以建聯合索引,但組合列最好不要超過3列,返回的組合列越少越高效;

問題也隨之而來,組合列中哪個列在前哪個列在後呢?

一般,在等值查詢情況下,誰在前誰在後沒關係;如果一列是範圍查詢,一列是等值查詢,等值查詢列在前效率高;聯合索引中,如果針對其中一列的查詢單列比較多的時候,單列查詢在前。比如在某錶中,想對其code和pcode欄位建聯合索引,但是業務中有大量的查詢pcode的單列查詢操作,則聯合索引應該將pcode放在前面比較合適。

上面說了這麼多索引的優點,那是不是建索引一定是有利的呢?

因為索引的有序特性,索引索引越多,為了維持索引有序,更新資料受到影響就會越大:

insert:每插入一條資料,就要維持索引有序,因此,索引對於插入操作有弊無利;

delete:刪除資料,如果資料量很大,對於定位要刪除的少量資料,條件列是索引列是有利的。如果刪除大量記錄或者索引列過多,對於刪除操作是有弊端的;

update:如果更新非索引列,則無影響;如果更新索引列,定位和更新索引列則和delete操作類似。

因為是將資料拿出來排序並且儲存到資料塊中,建索引時會鎖表,以免建索引過程中資料更新造成影響,所以,建索引尤其是大資料表,不要在使用高峰期建。

以上便是btree索引的一些簡單介紹啦,還請多多指正啊~

oracle 索引 之B TREE 索引

索引是oracle裡面的乙個非常重要的知識,oracle10g中索引可以分為以下 b tree indexes b tree cluster indexes hash cluster indexes reverse key indexes bitmap indexes bitmap join ind...

Oracle索引之Btree索引

日常開發中,對於資料的查詢如果需要優化,常聽說要加個索引。但是為什麼加了索引,資料的查詢就快了呢?那是不是加了索引就一定會是有效或者有利的呢?oracle中常見有btree索引,位圖索引和函式索引。我們今天就先介紹一下這個btree索引吧。既然叫btree索引,那就從它的樹結構說起 建btree索引...

mysql索引hash索引和b tree索引的區別

mysql下增加索引的方式 修改表結構 alter mytable add index indexname on username length 建立表結構 create table mytable id int not null,username varchar 16 not null,index...