在表上建立索引,索引對於表,就像目錄對於書一樣,有了索引可以直接定位到表中的數據位置,大大的加快查找速度。索引可以減少磁盤IO,在邏輯上和物理上都獨立於表的數據,索引可以存放在任何磁盤上面,此外Oracle會自動維護索引。
1.唯一索引、組合索引、反向鍵索引、函數索引、位圖索引
索引可以分爲B樹(B-Tree)索引和位圖(Bitmap)索引,B樹索引又分爲唯一索引、組合索引、反向鍵索引、基於函數的索引。學過數據結構的都知道B樹,所有葉子節點都在同一個深度。每個節點塊可以包含關鍵字: 比如某個節點塊包含了關鍵字有 100,200 500,那麼他的葉子節點就有四個,數據範圍分別是 ...~100、100~200, 200~500 ,500~....。
創建索引最簡單的語法: CREATE INDEX [索引名] ON [表名](表字段名)。 表名 user_indexes 、all_indexes可以看索引信息。表名user_ind_columns、all_ind_columns 查看索引的關聯信息。
索引碎片,指的是當索引關聯的數據如果被刪除,而索引信息還存在,那麼這個數據的索引就是無用的索引稱爲索引碎片,無用的信息佔用內存這樣會影響到Oracle性能。減少碎片的方法之一就是重建索引。
分析索引語句: ANALYZE INDEX [索引名] VALIDATE STRUCTURE; 然後查詢 INDEX_STATS查看pct_used 的索引碎片的多少。
首先先創建一個1300000個數據的表。來看看索引的效果。
--drop table salary_tbl;
create table salary_tbl(
employer_nm varchar(20),
department varchar(20) not null,
salary number not null,
leader_nm varchar(20)
);
truncate table salary_tbl;
begin
for i in 1..1300000
loop
insert into salary_tbl values('僱傭者'||i,'部門'||Mod(i,50),100+sqrt(i),'僱傭者'||Mod(i,20));
if Mod(i,1000)=0 then
commit;
end if;
end loop;
end;
/
commit;
新建索引,並查詢信息:
create index idx1 on salary_tbl(DEPARTMENT);
ANALYZE INDEX IDX1 VALIDATE STRUCTURE; --分析索引
select s.name,s.pct_used,s.blocks from INDEX_STATS s ;
此時是沒有索引碎片的,因爲指定的PCT_USED 最大值就是90.
刪除數據後再分析索引,查看索引信息:
此時的PCT_USED 使用率下降了,這就產生了索引碎片。想使使用率上升,其中一個方法就是重建索引:
ALTER INDEX IDX1 REBUILD; -- ALTER INDEX [索引名] REBUILD
ANALYZE INDEX IDX1 VALIDATE STRUCTURE;
select s.name,s.pct_used,s.blocks from INDEX_STATS s ;
重建索引後,使用率又上去了。
唯一索引:確保索引關聯的列上沒有重複值就叫做唯一索引,create unique index [索引名] on [表名](列名); unique表示獨一無二,不能重複。索引關聯的字段值不能重複,否則會報錯,但是關聯字段允許有多個空值。
組合索引: 索引可以關聯多個字段,關聯多個字段的索引叫組合索引。create index [索引名] on [表名](列名1,列名2...),這樣可以加快查詢的語句是 select * from [table] where 列名1 = .. and 列名2... 這樣的語句。
反向鍵索引:Oracle爲了平均分散數據到各索引葉子節點上,避免某些葉子節點數據量太大而有些葉子節點過小問題,提供了反向鍵索引。鍵值逆序排序,和一般索引相比如果鍵值連續在一起的,這表示都放在同一個數據塊中,當要存取兩個相鄰的鍵值時,將會造成同時去搶同一個數據塊。反向鍵值的話,兩個相鄰的鍵值不會放到同一個數據塊中,就不會發生互搶了,但是由於鍵值的關係已經沒有了,葉子快沒有雙向連接的功能。所以,SQL語法條件是 = 時 ,才能產生最大的作用。
create index [索引名] on [表名](列名) REVERES;
例如關聯的字段值是 1001 1002, 3211, 3212 ,3213 ,那麼反向鍵值就是 1001 2001 1123 2123 3123,用該值來建立索引。
函數索引:關聯的鍵值是通過函數計算的值,在where 函數(字段的時候)= ... 可以加快查詢速度。創建時需要有QUERY REWRITE權限,並且不能在 LOB類型的列上創建
create index [索引名] on [表名](函數名(參數)) ;
位圖索引 (Bitmap索引) : Bitmap索引不屬於B-Tree索引,兩者有很大的區別。B-Tree索引鍵值後面跟着ROWID,而BitMap索引,鍵值後面跟着串位(String of bit),串位也就是'0'和‘1’組成的字符串。位圖索引能夠有效地節省索引空間,它適合創建在低基數列上,所謂低基數列指的就是取值非常少的字段。比如 性別=(‘男‘,’女’); 年級=(‘1',‘2’,‘3’) 像這樣的。
create bitmap index [索引名] on [表名](列名) ;
B-Tree索引 | Bitmap索引 |
適合在索引鍵值比較多的時候,如學號、身份證等 | 適用於索引鍵值比較少的字段,如性別,血型,年級等 |
可以經常執行修改操作 | 執行修改操作的成本較高 |
對 ‘or’ 表達式很沒有效率 | 適用於 or 表達式的SQL語法 |
適用於線上交易系統(OTP),經常變化的系統 | 適用於數據倉庫,資料量大,但不經常變化的系統 |
重建索引完整語法: ALTER INDEX index_name REBULID [Online] [NOLOGING] [COMPUTE STATISTICS]
Online:在線重建索引,在重建索引的過程中,還允許其他用戶進行增刪改操作,如果要建立的索引數量過大,那麼建立索引的時間會較長,在一般情況下,這段時間禁止對索引進行增刪改,可能會對業務造成影響。設成Online就可以避免這個。
NOLOGGING:表示在重建過程中產生最少的重做條目 Redo Entry.
COMPUTE STATISTICS: 重建過程中就生成了優化器所需的統計信息,不需要重建之後再手動的來analyze 或者 dbms_stats.
2.索引的分區:
索引的分區有三種類型:局部分區索引、全局分區索引、全局非分區索引,分區索引可以在user_indexes 、user_ind_partitions表裏查找。
局部分區索引:在分區表上創建的索引,索引的分區範圍和表一致。create index [索引名] on [表名](字段) local ;表怎麼分區, 局部分區索引就怎樣分區。
全局分區索引:create index [索引名] on [表名](字段) global Partition by .......:手動給索引進行自定義分區。表的分區狀況和索引分區沒有關係,索引的分配在哪個區上是自定義的。
全局非分區索引:在分區表上創建的全局普通索引,索引不進行分區。create index [索引名] on [表名](字段) global;