oracle有哪些索引

2022-04-18 19:01:00

oracle的索引型別有:非唯一索引、唯一索引、點陣圖索引、區域性有字首分割區索引、區域性無字首分割區索引、全域性有字首分割區索引、雜湊分割區索引、基於函數的索引。索引需在表中插入資料後建立,唯一索引可用「create unique index」語句建立。

本教學操作環境:Windows7系統、Oracle 11g版、Dell G3電腦。

什麼是索引?

  • 索引是建立在表的一列或多個列上的輔助物件,目的是加快存取表中的資料;
  • Oracle儲存索引的資料結構是B*樹(平衡樹),點陣圖索引也是如此,只不過是葉子節點不同B*數索引;
  • 索引由根節點、分支節點和葉子節點組成,上級索引塊包含下級索引塊的索引資料,葉節點包含索引資料和確定行實際位置的rowid。

索引說明

1)索引是資料庫物件之一,用於加快資料的檢索,類似於書籍的索引。在資料庫中索引可以減少資料庫程式查詢結果時需要讀取的資料量,類似於在書籍中我們利用索引可以不用翻閱整本書即可找到想要的資訊。

2)索引是建立在表上的可選物件;索引的關鍵在於通過一組排序後的索引鍵來取代預設的全表掃描檢索方式,從而提高檢索效率

3)索引在邏輯上和物理上都與相關的表和資料無關,當建立或者刪除一個索引時,不會影響基本的表;

4)索引一旦建立,在表上進行DML操作時(例如在執行插入、修改或者刪除相關操作時),oracle會自動管理索引,索引刪除,不會對錶產生影響

5)索引對使用者是透明的,無論表上是否有索引,sql語句的用法不變

6)oracle建立主鍵時會自動在該列上建立索引

使用索引的目的:

  • 加快查詢速度
  • 減少I/O操作
  • 消除磁碟排序(索引能加快排序速度)

何時使用索引:

  • 查詢返回的記錄數 排序表<40%,對非排序表<7%
  • 表的碎片較多(頻繁增加、刪除)

索引的種類

  • 非唯一索引(最常用)
  • 唯一索引
  • 點陣圖索引
  • 區域性有字首分割區索引
  • 區域性無字首分割區索引
  • 全域性有字首分割區索引
  • 雜湊分割區索引
  • 基於函數的索引

管理索引的準則

  • 在表中插入資料後建立索引
  • 在用SQL*Loader或import工具插入或裝載資料後,建立索引比較有效;

索引正確的表和列

  • 經常檢索排序大表中40%或非排序表7%的行,建議建索引;
  • 為了改善多表關聯,索引列用於聯結;
  • 列中的值相對比較唯一;
  • 取值範圍(大:B*樹索引,小:點陣圖索引);
  • Date型列一般適合基於函數的索引;
  • 列中有許多空值,不適合建立索引

為效能而安排索引列

  • 經常一起使用多個欄位檢索記錄,組合索引比單索引更有效;
  • 把最常用的列放在最前面,例:dx_groupid_serv_id(groupid,serv_id),在where條件中使用groupidgroupid,serv_id,查詢將使用索引,若僅用到serv_id欄位,則索引無效;

合併/拆分不必要的索引。

限制每個表索引的數量

  • 一個表可以有幾百個索引(你會這樣做嗎?),但是對於頻繁插入和更新表,索引越多系統CPU,I/O負擔就越重;

  • 建議每張表不超過5個索引。

刪除不再需要的索引

  • 索引無效,集中表現在該使用基於函數的索引或點陣圖索引,而使用了B*樹索引;

  • 應用中的查詢不使用索引;

  • 重建索引之前必須先刪除索引,若用alter index … rebuild重建索引,則不必刪除索引。

索引資料塊空間使用

  • 建立索引時指定表空間,特別是在建立主鍵時,應明確指定表空間;
  • 合理設定pctfress,注意:不能給索引指定pctused;
  • 估計索引的大小和合理地設定儲存引數,預設為表空間大小,或initial與next設定成一樣大。

考慮並行建立索引

  • 對大表可以採用並行建立索引,在並行建立索引時,儲存引數被每個查詢伺服器程序分別使用,例如:initial1M,並行度為8,則建立索引期間至少要消耗8M空間;

考慮用nologging建立索引

  • 對大表建立索引可以使用nologging來減少重做紀錄檔;
  • 節省重做紀錄檔檔案的空間;
  • 縮短建立索引的時間;
  • 改善了並行建立大索引時的效能。

怎樣建立最佳索引?

明確地建立索引

create index index_name on table_name(field_name)
  tablespace tablespace_name
  pctfree 5
  initrans 2
  maxtrans 255
  storage
  (
  minextents 1
  maxextents 16382
  pctincrease 0
  );

建立基於函數的索引:

常用與UPPER、LOWER、TO_CHAR(date)等函數分類上,例:

create index idx_func on emp (UPPER(ename)) tablespace tablespace_name;

建立點陣圖索引:

對基數較小,且基數相對穩定的列建立索引時,首先應該考慮點陣圖索引,例:

create bitmap index idx_bitm on class (classno) tablespace tablespace_name;

明確地建立唯一索引

可以用create unique index語句來建立唯一索引,例:

create unique index dept_unique_idx on dept(dept_no) tablespace idx_1;

建立與約束相關的索引

可以用using index字句,為與uniqueprimary key約束相關的欄位建立索引,例如:

alter table table_name
  add constraint PK_primary_keyname primary key (field_name)
  using index tablespace tablespace_name;

如何建立區域性分割區索引

  • 基礎表必須是分割區表;
  • 分割區數量與基礎表相同;
  • 每個索引分割區的子分割區數量與相應的基礎表分割區相同;
  • 基礎表的子分割區中的行的索引項,被儲存在該索引的相應的子分割區中,例如:
  Create Index TG_CDR04_SERV_ID_IDX On TG_CDR04(SERV_ID)
  Pctfree 5  Tablespace TBS_AK01_IDX
  Storage (
  MaxExtents 32768  PctIncrease 0  FreeLists 1  FreeList Groups 1  )
  local  /

如何建立範圍分割區的全域性索引

基礎表可以是全域性表和分割區表。

create index idx_start_date on tg_cdr01(start_date)
  global partition by range(start_date)
  (partition p01_idx vlaues less than (‘0106’)
  partition p01_idx vlaues less than (‘0111’)
  …
  partition p01_idx vlaues less than (‘0401’ ))
  /

  重建現存的索引
  重建現存的索引的當前時刻不會影響查詢;

  重建索引可以刪除額外的資料塊;
  提高索引查詢效率;

alter index idx_name rebuild nologging;

  對於分割區索引:

alter index idx_name rebuild partition partiton_name nologging;

要刪除索引的原因

  • 不再需要的索引;
  • 索引沒有針對其相關的表所釋出的查詢提供所期望的效能改善;
  • 應用沒有用該索引來查詢資料;
  • 該索引無效,必須在重建之前刪除該索引;
  • 該索引已經變的太碎了,必須在重建之前刪除該索引;
  • 語句:
    drop index idx_name;
    drop index idx_name drop partition partition_name;

建立索引的代價

基礎表維護時,系統要同時維護索引,不合理的索引將嚴重影響系統資源,主要表現在CPU和I/O上;

插入、更新、刪除資料產生大量db file sequential read鎖等待;

一個表中有幾百萬條資料,對某個欄位加了索引,但是查詢時效能並沒有什麼提高,這主要可能是oracle的索引限制造成的。

oracle的索引有一些索引限制,在這些索引限制發生的情況下,即使已經加了索引,oracle還是會執行一次全表掃描,查詢的效能不會比不加索引有所提高,反而可能由於資料庫維護索引的系統開銷造成效能更差。

擴充套件知識:常見的索引限制問題

1、使用不等於操作符(<>, !=)

下面這種情況,即使在列dept_id有一個索引,查詢語句仍然執行一次全表掃描

select * from dept where staff_num <> 1000;

但是開發中的確需要這樣的查詢,難道沒有解決問題的辦法了嗎?

有!

通過把用 or 語法替代不等號進行查詢,就可以使用索引,以避免全表掃描:上面的語句改成下面這樣的,就可以使用索引了。

select * from dept shere staff_num < 1000 or dept_id > 1000;

2、使用 is null 或 is not null

使用 is nullis nuo null也會限制索引的使用,因為資料庫並沒有定義null值。如果被索引的列中有很多null,就不會使用這個索引(除非索引是一個點陣圖索引,關於點陣圖索引,會在以後的blog文章裡做詳細解釋)。在sql語句中使用null會造成很多麻煩。

解決這個問題的辦法就是:建表時把需要索引的列定義為非空(not null)

3、使用函數

如果沒有使用基於函數的索引,那麼where子句中對存在索引的列使用函數時,會使優化器忽略掉這些索引。下面的查詢就不會使用索引:

select * from staff where trunc(birthdate) = '01-MAY-82';

但是把函數應用在條件上,索引是可以生效的,把上面的語句改成下面的語句,就可以通過索引進行查詢。

select * from staff where birthdate < (to_date('01-MAY-82') + 0.9999);

4、比較不匹配的資料型別

比較不匹配的資料型別也是難於發現的效能問題之一。下面的例子中,dept_id是一個varchar2型的欄位,在這個欄位上有索引,但是下面的語句會執行全表掃描。

select * from dept where dept_id = 900198;

這是因為oracle會自動把where子句轉換成to_number(dept_id)=900198,就是3所說的情況,這樣就限制了索引的使用。把SQL語句改為如下形式就可以使用索引

select * from dept where dept_id = '900198';

5、使用like子句

使用like子句查詢時,資料需要把所有的記錄都遍歷來進行判斷,索引不能發揮作用,這種情況也要儘量避免。

Like 的字串中第一個字元如果是‘%’則用不到索引

Column1 like ‘aaa%’ 是可以的
Column1 like ‘%aaa%’用不到

6、使用IN

儘管In寫法要比exists簡單一些,exists一般來說效能要比In要高的多

In還是用Exists的時機

當in的集合比較小的時候,或者用Exists無法用到選擇性高的索引的時候,用In要好,否則就要用Exists
例:

select count(*) from person_info where xb in (select xb_id from dic_sex);

Select count(*) from n_acntbasic a where shbxdjm =:a and exists(select 1 from person_info where pid=a.pid and …);

Select * from person_info where zjhm=3101….;--將會對person_info全表掃描

Select * from person_info where zjhm =‘3101…’;--才能用到索引

假定TEST表的dt欄位是date型別的並且對dt建了索引。
如果要查‘20041010’一天的資料.下面的方法用不到索引

Select * from test where to_char(dt,’yyyymmdd’) =‘20041010’;

而以下將會用到索引。

select * from test where dt >=to_date(‘20041010’,’yyyymmdd’) and dt < to_date(‘20041010’,’yyyymmdd’) + 1

7、如果能不用到排序,則儘量避免排序。

用到排序的情況有
集合操作。Union ,minus ,intersect等,注:union all 是不排序的。

Order byGroup byDistinctIn

有時候也會用到排序
確實要排序的時候也儘量要排序小資料量,儘量讓排序在記憶體中執行,有文章說,記憶體排序的速度是硬碟排序的1萬倍。

在排序的欄位上建立索引,讓排序在記憶體中執行,加快排序速度。

8、在基於CBO的優化器(花費)下,表的統計資料過期。也可能導致不使用索引。

解決:執行表分析。獲取表的最新資訊。

9、獲取的資料量過大,全部掃描效率更高

10、索引欄位的值分散率太低,值太集中,如型別欄位都是1,2, 狀態型別Y-有效/N-無效。這型別的欄位最好別建索引。

儘管在這些欄位上建立了索引,但對全表資料區分度不大。最後還是會全表掃描。

以上就是oracle有哪些索引的詳細內容,更多請關注TW511.COM其它相關文章!