Oracle索引的原理及使用


Oracle索引的原理及使用

一、前引

  1. 索引在數據庫中扮演着非常重要的角色,是數據庫對象之一,用於加快數據的檢索,類似於書籍的目錄。在數據庫中索引可以減少數據庫程序查詢結果時需要讀取的數據量,類似於在書籍中我們利用索引可以不用翻閱整本書即可找到想要的信息。
  2. 索引是建立在表上的可選對象,索引的關鍵在於通過一組排序后的索引鍵來取代默認的全表掃描檢索方式,從而提高檢索效率
  3. 索引在邏輯上和物理上都與相關的表和數據無關,當創建或者刪除一個索引時,不會影響基本的表。
  4. 索引一旦建立,在表上進行DML操作時(例如在執行插入、修改或者刪除相關操作時),oracle會自動管理索引,索引刪除,不會對表產生影響。
  5. 索引對用戶是透明的,無論表上是否有索引,sql語句的用法不變。
  6. oracle創建主鍵時會自動在該列上創建索引。

二、索引原理

  1. 若沒有索引,搜索某個記錄時(例如查找name='張三')需要搜索所有的記錄,因為不能保證只有一個張三,必須全部搜索一遍。
  2. 若在name上建立索引,oracle會對全表進行一次搜索,將每條記錄的name值哪找升序排列(建立索引時做的),然后構建索引條目(name和rowid),存儲到索引段中,查詢name為張三時即可直接查找對應地方。
  3. 創建了索引並不一定就會使用,oracle自動統計表的信息后,決定是否使用索引,表中數據很少時使用全表掃描速度已經很快,沒有必要使用索引。
  4. 占用存儲空間:索引實際上也是一張表,記錄了主鍵與索引字段,一般以索引文件的形式存儲在磁盤上。
  5. 降低更新表的速度:表的數據發生了變化,對應的索引也需要一起變更,從而減低的更新速度。否則索引指向的物理數據可能不對,這也是索引失效的原因之一。
  6. 特大型的表,建立和使用索引的代價隨着增長,可以使用分區技術來解決。

三、使用

  1. 語法
CREATE [UNIQUE] | [BITMAP] INDEX index_name  --unique表示唯一索引
ON table_name([column1 [ASC|DESC],column2    --bitmap,創建位圖索引
[ASC|DESC],…] | [express]) [TABLESPACE tablespace_name]
[PCTFREE n1]                                 --指定索引在數據塊中空閑空間
[STORAGE (INITIAL n2)]
[NOLOGGING]                                  --表示創建和重建索引時允許對表做DML操作,默認情況下不應該使用
[NOLINE]
[NOSORT];                                    --表示創建索引時不進行排序,默認不適用,如果數據已經是按照該索引順序排列的可以使用

例子:

--給列 localid 添加索引(索引名稱一般就是表名加個index_列名)
create Index index_localid_STATATIC_YEAR on STATATIC_YEAR(localid);
  1. 修改索引
alter index index_localid_STATATIC_YEAR rename to bitmap_index;
  1. 合並索引( 表使用一段時間后在索引中會產生碎片,此時索引效率會降低,可以選擇重建索引或者合並索引,合並索引方式更好些,無需額外存儲空間,代價較低)
alter index index_localid_STATATIC_YEAR coalesce;
  1. 重建索引
  • 方式一:刪除原來的索引,重新建立索引

  • 方式二:

    alter index index_localid_STATATIC_YEAR rebuild;
    
  1. 刪除索引
drop index index_localid_STATATIC_YEAR;
  1. 查看索引
---查詢索引
select * from user_indexes where table_name='PEOPLE' 

select index_name,index-type, tablespace_name, uniqueness from all_indexes where table_name ='tablename'; 
-- 創建例子
create index index_sno on student('name'); 
select * from all_indexes where table_name='student';

四、索引分類

B樹索引(默認索引)

  1. 創建
craete index index_sno on student('sno');
  1. 說明

    • oracle中最常用的索引;
    • B樹索引就是一顆二叉樹;
    • 葉子節點(雙向鏈表)包含索引列和指向表中每個匹配行的ROWID值;
    • 所有葉子節點具有相同的深度,因而不管查詢條件怎樣,查詢速度基本相同;
    • 能夠適應精確查詢、模糊查詢和比較查詢;
  2. 使用場景

    列基數(列不重復值的個數)大時適合使用B數索引

位圖索引

  1. 創建
create bitmap index index_sno on student(sno);
  1. 說明

    • 創建位圖索引時,oracle會掃描整張表,並為索引列的每個取值建立一個位圖(位圖中,對表中每一行使用一位(bit,0或者1)來標識該行是否包含該位圖的索引列的取值,如果為1,表示對應的rowid所在的記錄包含該位圖索引列值),最后通過位圖索引中的映射函數完成位到行的ROWID的轉換。
  2. 使用場景

    對於基數小的列適合簡歷位圖索引(例如性別等)

復合索引(基於多個列創建)

  1. 創建
craete index index_sno on student('sno','sex');
  1. 說明
    • 創建符合索引時,注意多個列的前后順序,會影響查詢的效率。
    • 選擇經常在WHERE中使用,並且是由AND進行連接的列做符合索引列。
    • 選擇WHERE中使用頻率相對較高的列排在前面,或者根據需要為其他列創建單獨的索引。
    • 只有復合索引中的第一列被WHERE子句使用時,Oracle才會使用該復合索引。

函數索引

  1. 創建
create index fbi on student (upper(name)); 
select * from student where upper(name) ='WISH';
  1. 說明
    • 當經常要訪問一些函數或者表達式時,可以將其存儲在索引中,這樣下次訪問時,該值已經計算出來了,可以加快查詢速度。
    • 函數索引中可以使用len、trim、substr、upper(每行返回獨立結果),不能使用如sum、max、min、avg等。
-- 常用函數
-- lower:大寫字符轉化成百小寫的函數
  select lower(表中字段) from 表名 --將表里的字問段信息中含有字母答的全部轉回成小寫
-- upper:小寫字答符轉化成大寫的函數
  select upper(表中字段) from 表名 --將 user表里的字段信息中含有字母的全部轉成大寫
-- substr:切割字符串
create index t_object_type_idn_fun on t(substr(object_type,1,3));
select * from t  where  substr(t.object_type,1,3)='XXX';

五、索引建立原則

  1. 如果有兩個或者以上的索引,其中有一個唯一性索引,而其他是非唯一,這種情況下oracle將使用唯一性索引而完全忽略非唯一性索引
  2. 至少要包含組合索引的第一列(即如果索引建立在多個列上,只有它的第一個列被where子句引用時,優化器才會使用該索引)
  3. 小表不要簡歷索引
  4. 對於基數大的列適合建立B樹索引,對於基數小的列適合簡歷位圖索引
  5. 列中有很多空值,但經常查詢該列上非空記錄時應該建立索引
  6. 經常進行連接查詢的列應該創建索引
  7. 使用create index時要將最常查詢的列放在最前面
  8. LONG(可變長字符串數據,最長2G)和LONG RAW(可變長二進制數據,最長2G)列不能創建索引。
  9. 限制表中索引的數量(創建索引耗費時間,並且隨數據量的增大而增大;索引會占用物理空間;當對表中的數據進行增加、刪除和修改的時候,索引也要動態的維護,降低了數據的維護速度)

六、舉個栗子

  1. 通配符在搜索詞首出現時,oracle不能使用索引
--在name上創建索引;
create index index_name on student('name'); 
--下面的方式oracle不適用name索引
select * from student where name like '%wish%'; 
--如果通配符出現在字符串的其他位置時,優化器能夠利用索引
select * from student where name like 'wish%';
  1. 不要在索引列上使用not,可以采用其他方式代替如下:(oracle碰到not會停止使用索引,而采用全表掃描)
select * from student where not (score=100);
select * from student where score <> 100; 
--替換為
select * from student where score>100 or score <100
  1. 索引上使用空值比較停止使用索引
select * from student where score is not null;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM