索引就好象一本字典的目錄。憑藉字典的目錄,我們可以非常迅速的找到我們所需要的條目。資料庫也是如此。憑藉oracle資料庫的索引,相關語句可以迅速的定位記錄的位置,而不必去定位整個表。
雖然說,在表中是否建立索引,不會影響到oracle資料庫的使用,也不會影響資料庫語句的使用。這就好像即使字典沒有目錄的話,使用者仍然可以使用它一樣。可是,若字典沒有目錄,那麼可想而知,使用者要查某個條目的話,其不得不翻遍整本字典。資料庫也是如此。若沒有建立相關索引的話,則資料庫在查詢記錄的時候,不得不去查詢整個表。當表中的記錄比較多的時候,其查詢效率就會很低。所以,合適的索引,是提高資料庫執行效率的乙個很好的工具。
不過,並不是說表上的索引越多越好。過之而不及。故在資料庫設計過程中,還是需要為表選擇一些合適的索引。寧缺勿濫,這是建立索引時的乙個遵循標準。在理論上,雖然乙個表可以設定無限的索引。但是,資料庫管理員需要知道,表中的索引越多,維護索引所需要的開銷也就越大。每當資料表中記錄有增加、刪除、更新變化的時候,資料庫系統都需要對所有索引進行更新。故資料庫表中的索引絕對不是多多益善。具體來說,在索引建立上,筆者對大家有如下建議。
建議一:在基數小的字段上要善於使用位圖索引。
基數是點陣圖索引中的乙個基本的定義,它是指資料庫表中某個字段內容中不重複的數值。如在員工資訊表中的性別字段,一般就只有男跟女兩個值,所以,其基數為2;婚姻狀況字段的話,則其只有已婚、未婚、離婚三種狀態,其基數就為3;民族一覽內也是只有有限的幾個值。
對於要查詢基數小的字段,如現在使用者想查詢所有婚姻狀況為「已婚」的「女性」時,利用位圖索引可以提高查詢的效率。這主要是因為標準索引是通過在索引中儲存排序過的索引列以及對應的rowid來實現的。若我們在基數小的列上建立標準索引的話,則其會返回大量的記錄。
而當我們在建立位圖索引的時候,在oracle會對整個表進行掃瞄,並且會為索引列的每個取值建立乙個位圖。若內容相同,則在位圖上會以乙個相同的數字表示。此時,若這個欄位的基數比較小的話,則若需要實現對整個欄位的查詢的話,效率就會非常的高。因為此時,資料庫只要點陣圖中數字相同的內容找出來即可。
除了在資料表某列基數比較小的情況下,採用位圖索引外,我們往往在一些特殊的情況下,也會建議採用位圖索引。最常見的情況是,在where限制條件中,若我們多次採用and或者or條件時,也建議採用位圖索引。因為當乙個查詢飲用了一些部署了點陣圖索引的列的時候,這些位圖可以很方便的與and或者or 運算子操作結合以快速的找出使用者所需要的記錄。
但是,這裡要注意,不是在條件語句中包含運算子的時候,採用位圖索引都能夠提供比較高的效率。一般來說,只有and 或者or運算子的時候,位圖索引才會比較具有優勢。若此時使用者採用大於號或者不等於號作為條件語句中的限制條件的時候,則往往採用標準索引具有更大的優勢。
所以,筆者在資料庫設定中,一般只有在三種情況下才採用位圖索引。一是列的基數比較小,而有可能需要根據這些欄位的內容查詢相關的記錄;二是在條件語句中,用到了and或者or運算子的時候。除了這兩種情況外,最好能夠採用其他適合的索引。第三種情況是,需要用到null作為查詢的限制條件。因為標準查詢一般情況下,會忽略所有的null值列。也就是說,若需要查詢「所有沒有身份證號碼」的員工的資訊的時候,標準索引並不能夠起到加速查詢速度的作用。此時,就需要採用位圖索引。因為位圖索引會記錄相關的null值列資訊。
建議二:建立索引的一些限制條件。
並不說,表或者列建立的索引越多越好。相反,索引建的越多,有時會反而會影響資料庫執行的整體效能。所以,在建立索引的時候,仍然會有一些限制條件。
一是不要對一些記錄內容比較少的表建立索引。在乙個應用系統設計的時候,如設計乙個erp系統的資料庫,其雖然有幾千張表。但是,並不是每張表都有大量記錄的。相反,其中有近一半左右的資料表,可能其儲存的資料不會超過百條。如員工登陸帳戶密碼表、企業部門資訊表等等。對於這些記錄內容比較少的表,我們建立最好不要為其建立索引。無論是表上的,還是欄位上,都不要建立索引。
二是若表中的內容比較大,但是,這個表基本上不怎麼查詢的時候,則只需要在表上建立索引即可;而不需要在字段上建立索引。如現在在erp系統中,有一張表是「ad_table」。其儲存的是這個資料庫中相關表的資訊。這張表只有在資料庫設計的時候才會用到。故這張表中的記錄雖然比較多,但是由於使用者用的比較少,所以,一般沒有必要為這張表建立列級別上的索引。而直接用表索引來代替。
三是在一些null欄位上,要根據實際情況來判斷是否要建立索引。如現在有一張人事檔案的**,其上面有兩個字段,分別為「身份證號碼」與「地區」。有時會為了某個原因,企業需要所有員工都在系統中登記他們的身份證號碼,以方便他們辦工資卡、社會保險等等。所以人事管理可能需要經常的查詢系統,看看有沒有沒有身份證號碼的員工資訊。此時,就需要利用條件「is null」來查詢我們所需要的記錄。故為了提高查詢效率,若某個記錄可能為空,並且經常需要以null為條件進行查詢的時候,則最好給這個字段新增乙個索引,並且最好建立位圖索引。相反,若雖然可能會以null這個條件作為查詢的限制語句,但是,用的不是很多的時候,則就沒有必要為其建立索引。
建議三:多表連線查詢的索引設計。
如現在有乙個人事管理系統。人事經理想知道員工的社保繳納情況。他需要知道員工的姓名、職務、戶籍性質(農民戶口跟居民戶口費用不一樣)、繳納的情況等等。但是,這些資訊包含在不同的表中。因為為了提高資料庫的效能,在表中儲存的可能只是某些序號,而不是具體的內容。如在社保表中,儲存的是員工對應的編號,而不是員工的名字。所以,要得到這份報表的話,就可能需要關聯員工基本資訊表、公司組織結構表等**,才能夠查詢到使用者所需要的內容。
為此,就需要利用join語句,把這些**關聯起來。為了提高資料庫的查詢效率,這些用來關聯的字段,最好能夠建立索引。這可以顯著的提高查詢的速度。
建議四:在表的更新速度與查詢速度之間尋求乙個平衡點。
眾所周知,索引本身並不影響資料庫的使用,其主要是為了提高資料庫的查詢效率。但是,由於當資料庫的表中的資料更新的時候,包括記錄的增加、刪除、更改等等,都會對雖有的索引進行更新。
很明顯,索引雖然可以提高查詢速度。但是,也會對一些表的更新操作產生不良的影響。當在表中建立的索引越多,這個不利影響也會越大。故資料庫管理員在設定索引的時候,還需要注意,在這兩個之間需要乙個均衡點。
按照一般的理論來說,當某個表多數用來查詢、更新相對來說比較上的話,則要多多採用索引。相反,當某個表記錄更新居主導,查詢相對來說比較少的話,則不要建立太多的索引,避免對更新的速度差生不利影響。
在實際工作中,若某個表頻繁的被檢視所呼叫的話,則最好就好設定比較多的索引了。
1、在有索引的表上執行dml操作效能會變慢,因為同時要往表和索引插入資料。
2、當表中如果有組合索引時,如create index idx_tables on t_user_info(id,name,address);
使用select語句進行查詢時,where條件中一定要用到前導引,這樣oracle才能用到該索引進行掃瞄,
否則就進行全表掃瞄。
3、索引只能用於查詢表中已經存在的資料。如果查詢語句中有<>或!=的時候,oracle同樣不會用到索引,
解決方案:可以用 where t.name>'huangyun' or t.name<'huangyun'
4、避免使用is null或者 not null。使用技巧:null關鍵字通常會限制使用索引,所以在create table的
時候盡量使用not null或者default,這樣可以避免出現效能的問題。
2.11 索引的型別有: b-樹索引,位圖索引,hash索引,索引編排表,反轉鍵索引,基於函式的索引,分割槽索引
本地和全域性索引。
2.11.1 b-樹索引是oracle中的通用索引,也是oracle中的預設索引,當建立索引時如果不指定特定的索引型別
oracle則預設的是b-樹索引。b-樹索引可以乙個列上的索引,也可以是多列上的索引,但指定的列不能
超過32列。索引只能在有值的列上有作用。
2.11.6 基於函式的索引,在建立索引是可以使用
create index idx_user_info_name on userinfo(max(name))
於是在使用查詢語句的時候 select * from userinfo t where max(name)='huangyun'
就已經使用了該列上的索引,但建立這種索引的時候一定要謹慎,需要考慮額外的代價。
基於函式的索引的例項如下
select count(1) from userinfo where ratio(name,age)>5; finished 20分鐘
create index idx_ratio_userinfo on userinfo(name,age);
select count(1) from userinfo where ratio(name,age)>5; finished 7秒鐘
//ratio函式是自定義的函式。
2.11.7分割槽索引
分割槽索引簡單的說就是把乙個索引劃分為多個片斷,並且這些片斷可以分布在不同的硬碟上。
b-索引和點陣圖索引可以建立分割槽索引,但hash索引不可以被分割槽??
Oracle資料庫中如何選擇合適的索引型別
索引就好象一本字典的目錄。憑藉字典的目錄,我們可以非常迅速的找到我們所需要的條目。資料庫也是如此。憑藉oracle資料庫的索引,相關語句可以迅速的定位記錄的位置,而不必去定位整個表。雖然說,在表中是否建立索引,不會影響到oracle資料庫的使用,也不會影響資料庫語句的使用。這就好像即使字典沒有目錄的...
Oracle資料庫中如何選擇合適的索引型別
索引就好象一本字典的目錄。憑藉字典的目錄,我們可以非常迅速的找到我們所需要的條目。資料庫也是如此。憑藉oracle資料庫的索引,相關語句可以迅速的定位記錄的位置,而不必去定位整個表。雖然說,在表中是否建立索引,不會影響到oracle資料庫的使用,也不會影響資料庫語句的使用。這就好像即使字典沒有目錄的...
Oracle資料庫中如何選擇合適的索引型別
索引就好象一本字典的目錄。憑藉字典的目錄,我們可以非常迅速的找到我們所需要的條目。資料庫也是如此。憑藉oracle資料庫的索引,相關語句可以迅速的定位記錄的位置,而不必去定位整個表。雖然說,在表中是否建立索引,不會影響到oracle資料庫的使用,也不會影響資料庫語句的使用。這就好像即使字典沒有目錄的...