索引的使用場景:
1.對應的索引字段經常被查詢,且返回的數據結果佔總數據量的一小部分
2.有外鍵約束的單個或多個字段上,需要建立索引。避免在更新主表的主鍵值,插入數據或刪除數據時,對整張表的表鎖出現。
3.唯一鍵約束,有相對應的索引存在
索引的屬性:
索引與表中數據獨立,增加或刪除索引對錶數據庫無影響,只不過對應數據查詢速度變慢,索引會降低dml操作性能(需要額外更新索引數據)
1.可用性
默認屬性爲可用,一個unuseable索引,dml操作不在維護對應索引且被優化器忽略,相對於刪除一個索引繼而創建它,可使用使索引不可用然後rebuild。無效索引或分區索引不佔用空間,當把索引置成無效時,對應的存儲空間被刪掉,(對應分配的區段給刪除掉).
2.可見性
默認可見。一個invisible索引,dml操作進行維護,默認優化器不使用此索引。把一個索引置成不可見,是刪除它或者更改爲無效狀態兩者中的一種。把索引置成不可見非常有用,在刪除以前移除索引或臨時使用索引對應所有應用都沒有影響。
相同字段不同順序可以創建不同索引。
例如:create index ind_1 on halee(empno,ename);
create index ind_2 on halee(ename,empno);
index scan:I/O次數跟使用的索引的高度一致,在一次查詢數據中。
full index scan:當謂語(where clause)中包含索引字段的過濾條件,都會走索引全掃描,前提是必須前置字段在前,如果排序字段與創建索引順序不同,則不會使用索引全掃描
例如:全索引掃描場景
索引創建順序爲 empno,ename,sal;
1.查詢字段全部在索引裏,直接從索引中獲取不在訪問對應表
explain plan for
select empno,ename,sal from marlie where sal >= 3000 order by empno,ename;
-----
Plan hash value: 3148600482
--------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 3 | 99 | 1 (0)| 00:00:01 |
|* 1 | INDEX FULL SCAN | IND_MARLIE_COMPLI | 3 | 99 | 1 (0)| 00:00:01 |
--------------------------------------------------------------------------------------
2.查詢除了索引字段以前的其他字段,需要通過索引rowid來訪問表來回去對應數據值
explain plan for
select empno,ename,sal,HIREDATE from marlie where sal >= 3000 order by empno,ename;
--------------
Plan hash value: 3449361140
-------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 3 | 126 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| MARLIE | 3 | 126 | 2 (0)| 00:00:01 |
|* 2 | INDEX FULL SCAN | IND_MARLIE_COMPLI | 1 | | 1 (0)| 00:00:01 |
3.查詢字段只包括索引字段,排序非創建順序,需要有額外排序操作
explain plan for
select empno,ename,sal from marlie where sal >= 3000 order by ename,empno;
--------------------
Plan hash value: 584562644
--------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 3 | 99 | 2 (50)| 00:00:01 |
| 1 | SORT ORDER BY | | 3 | 99 | 2 (50)| 00:00:01 |
|* 2 | INDEX FULL SCAN| IND_MARLIE_COMPLI | 3 | 99 | 1 (0)| 00:00:01 |
4.查詢字段除索引字段外還有其他字段,排序非創建順序,直接不會走索引全所描
explain plan for
select empno,ename,sal,HIREDATE from marlie where sal >= 3000 order by ename,empno;
-------------
Plan hash value: 1152818333
-----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 3 | 126 | 4 (25)| 00:00:01 |
| 1 | SORT ORDER BY | | 3 | 126 | 4 (25)| 00:00:01 |
|* 2 | TABLE ACCESS FULL| MARLIE | 3 | 126 | 3 (0)| 00:00:01 |
fast full index scan:屬於full index scan一種,當查詢的字段全部在索引裏,且沒有特殊的排序要求。
以下兩種情況會替代全表掃描:
1.索引包含所有的查詢字段
2.一行數據全部爲null的值不會顯示在結果集中
2.1.索引字段有一個字段有not null約束
2.2.where條件裏有過濾null值的條件,保證全部爲null的不展示出來
index range scan:
where條件中索引字段對應有過濾條件,且索引不是唯一索引,一個key對應多個rowid,就會使用索引範圍掃描,在條件中有範圍查詢 between and,會走index range scan。
explain plan for
select empno,ename,sal,deptno from marlie where empno=7521;-- 索引字段出現在where中
----
Plan hash value: 3540606923
-------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 46 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| MARLIE | 1 | 46 | 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | IND_MARLIE_COMPLI | 1 | | 1 (0)| 00:00:01 |
index unique scan:
一個key對應0或1條數據,where條件爲等值查詢,索引字段爲唯一鍵值,當查詢到一個符合條件的記錄即可會停止對應查詢進程。與index range scan對應。
在empno字段創建了唯一索引
explain plan for
select empno,ename,sal,deptno from marlie where empno=7521;
------
Plan hash value: 260264523
-------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 17 | 1 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| MARLIE | 1 | 17 | 1 (0)| 00:00:01 |
|* 2 | INDEX UNIQUE SCAN | UIND_MARLIE_EMPNO | 1 | | 0 (0)| 00:00:01 |
index skip scan:
使用符合索引的邏輯子索引進行掃描獲取數據。在複合索引前導列數據只有很少的幾個值,非前導列有很多非重複的值,在where條件中使用非前導列查詢時,會走index skip scan.
邏輯上按照前導列的非重複值的個數,把複合索引分成若干個子索引。
舉例如下:
在表halee中創建 sex,id複合索引,分析表後:
explain plan for
select * from halee where id = 2050;
----
Plan hash value: 1329500493
----------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 2 | 14 | 4 (0)| 00:00:01 |
|* 1 | INDEX SKIP SCAN | IND_HALEE_COM | 2 | 14 | 4 (0)| 00:00:01 |
實際執行類似:
select * from halee where sex = 1 and id = 2050
union all
select * from halee where sex = 0 and id = 2050;
index clustering factor:
用於衡量索引數據排序是否工整,順序排列對應的相鄰葉子塊 對應的行存儲在同一個數據塊中(讀取數據都是按照塊讀取的),這樣可降低IO次數,索引聚集因子就很小,接近於表數據對應的塊個數。
只有儘可能的降低表的集羣因子。一個索引怎麼查詢都不走索引或強制執行花費更大,有可能是集羣因子過大導致。
reserve key indexes:把字段值對應的十六進制 按照倒敘的順序存儲
優點:避免熱塊操作,特別是在rac中,不同的實例操作相同的數據塊。增加了插入性能。
缺點:在範圍查詢中,不能使用反轉索引進行查詢。
ascending and descending indexes:
ascending :以升序的方式存儲數據,默認情況下,字符串類型按照值對應的字節數存儲,數字類型按照從小大小數據,時間類型按照從古至今的方式存儲。
descending:以倒敘的方式存儲數據。
優點:在索引字段對應排序時,不需要額外的排序操作。
key compression:可以壓縮主鍵對應的b-tree索引,或者是索引組織表;鍵值壓縮,可以大大縮小索引存儲所需空間。
每個索引都有公共部分(group piece)及唯一部分(unique piece),壓縮後更改爲 前綴部分(prefix)和後綴部分(suffix),prefix對應group piece,suffix對應unqiue piece,prefix對應索引對應的字段值,suffix對應rowid
壓縮前,存儲類似: | 壓縮後 |
20 1234 AAASMSAAEAAAACzAAA 20 1234 AAASMSAAEAAAACzAAB 30 2154 AAASMSAAEAAAACzAAC 40 1111 AAASMSAAEAAAACzAAD 40 1112 AAASMSAAEAAAACzAAE | 20 1234 AAASMSAAEAAAACzAAA AAASMSAAEAAAACzAAB 30 2145 AAASMSAAEAAAACzAAC 40 1111 AAASMSAAEAAAACzAAD 40 1112 AAASMSAAEAAAACzAAE |
位圖索引(bitmap index)
適用環境:
字段中數據基數少,即唯一值不多。
表中更新少或幾乎沒有.
表中更新數據時,直接把索引鍵對應的值所有的行都進行鎖定,不是鎖定某一更改的行。
針對與某個bitmap索引,每一行都有一個對應的值來標識該行數據是否滿足索引要求
存儲如下:
col_value | row1 | row2 | row3 | row4 | row5 | row6 | row7 |
M | 1 | 0 | 0 | 0 | 1 | 1 | 1 |
F | 0 | 1 | 1 | 1 | 0 | 0 | 0 |
針對bitmap類型的值來進行計算數量等類似的查詢,可以創建愛你bitmap join index
例如在dept.dname字段上創建bitmap索引,基表爲emp
create bitmap index bind_emp_dep_dname on emp(dept.dname)
from emp,dept where emp.deptno=dept.deptno;
類似如下的查詢,會直接返回結果:
select count(*) from emp,dept where emp.deptno=dept.deptno and dname='ACCOUNTING';
bitmap index存儲:
使用b-tree的方式存儲每個索引鍵值,每個位圖都存儲在葉子節點上。
每個位圖索引以b-tree方式存儲有下面三部分組成:
每個索引值以索引鍵值開頭
每個範圍以rowid最小值和最大值標誌
每個範圍內的rowid的位圖值