Oracle索引如何提高數(shù)據(jù)庫的查詢效率
Oracle索引可以說在很大程度上提高了數(shù)據(jù)庫的相關(guān)查詢效率。但是我們?nèi)绻麑λ饕氖褂貌划?dāng)時(shí),那么就會反而引起相反的效果。如下圖所示的表,該采用什么索引呢?筆者借這個(gè)機(jī)會,跟大家討論一下位圖索引的使用時(shí)機(jī)以及注意事項(xiàng)。
眾所周知,索引可以在很大程度上提高數(shù)據(jù)庫的查詢效率。但是如果索引使用不當(dāng),如在不恰當(dāng)?shù)牡胤讲捎昧瞬磺‘?dāng)?shù)乃饕?,那么反而會起到適得其反的效果。如下圖所示的表,該采用什么索引呢?筆者借這個(gè)機(jī)會,跟大家討論一下位圖索引的使用時(shí)機(jī)以及注意事項(xiàng)。
一、 B樹索引的缺陷
在實(shí)際工作中,B樹索引是Oracle數(shù)據(jù)庫中最常用的一種索引。如在使用Create Index語句創(chuàng)建索引的時(shí)候,默認(rèn)采用的就是B樹索引。在B樹索引中,是通過在索引中保存排序過的索引列以及其對應(yīng)的Rowid列的值來實(shí)現(xiàn)的。不過對于某些比較特殊的情況,如基數(shù)比較小的列,使用這個(gè)B樹索引反而會降低數(shù)據(jù)庫的查詢效率。
基數(shù)在Oracle數(shù)據(jù)庫中指的是某個(gè)列可能擁有的不重復(fù)數(shù)值的個(gè)數(shù)。如上圖為例,SEX指員工的性別,一般就只有男女兩個(gè)值(其中1代表男、0代表女),其基數(shù)就為2。假設(shè)企業(yè)要組織公司所有的女員工出去旅游,作為三八婦女節(jié)的禮物。為此就需要查詢出公司所有女員工的信息。此時(shí)如果在性別列上加入B樹索引,那么反而會得到適得其反的效果。查詢效率不但沒有提升,反而下降。
在這些基數(shù)比較小的列上創(chuàng)建B樹索引并對其進(jìn)行查詢的話,系統(tǒng)就會返回大量的記錄。因而這并不是具有高度選擇性的索引,并不能夠顯著提高查詢的速度。當(dāng)然并不是說B樹索引不好,而是指其沒有用對地方。
二、 位圖索引的特點(diǎn)以及使用時(shí)機(jī)
在數(shù)據(jù)庫中(包括Sql Server數(shù)據(jù)庫),對于這種基數(shù)比較小的列,如果只有有限的幾個(gè)固定值,如上表中的性別、婚姻狀況等等,要為其建立索引的話,采用的就應(yīng)該是位圖索引,而不是B樹索引。
位圖索引為什么可以提高基數(shù)比較小的表的查詢速度呢?這主要是因?yàn)樵趧?chuàng)建Oracle位圖索引的時(shí)候,數(shù)據(jù)庫往往會對整個(gè)表進(jìn)行掃描,并未索引列的每個(gè)取值建立一個(gè)位圖(位圖索引的名字也由此而來)。在這個(gè)位圖中,為表中的每一行使用一個(gè)位元來表示該行是否包含該位圖的索引列的取值。位元到行的ROWID的對應(yīng)關(guān)系通過位圖索引中的應(yīng)收函數(shù)來完成。如此的話,位圖索引就能夠以一種完全不同的內(nèi)部機(jī)制來完成與B樹索引相同的功能。
另外值得一提的是,對于B樹索引而言,如果在查詢條件語句中采用了AND等操作符號,其查詢的效率會大打折扣。故在數(shù)據(jù)庫優(yōu)化中,會建議大家不要使用這些操作符,改用其他操作符代替。不過如果采用Oracle位圖索引的話,則沒有這方面的顧慮。如上例所示,假設(shè)用戶需要查找已婚的女性,那么就可以使用如下的語句查詢。
- select t.*, t.rowid
- from userinfo t
- where t.merital=’已婚’ and t.sex=0
這個(gè)查詢引用了一些創(chuàng)建了Oracle位圖索引的列時(shí),這些位圖可以很方便的與AND或者OR操作符結(jié)合以找出想要的數(shù)據(jù)。數(shù)據(jù)庫在后臺處理的時(shí)候,先利用已經(jīng)創(chuàng)建的位圖進(jìn)行邏輯運(yùn)算,然后計(jì)算結(jié)果位圖中1的個(gè)數(shù),就可以查詢到滿足條件的所有記錄。如果查詢到結(jié)果后還需要更改數(shù)據(jù)的話,那么只需要按照結(jié)果位圖中取1的位元對應(yīng)的ROWID列的值進(jìn)行映射即可。
【編輯推薦】