學習-索引

索引的使用場景:
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)

適用環境:

  1. 字段中數據基數少,即唯一值不多。

  2. 表中更新少或幾乎沒有.

表中更新數據時,直接把索引鍵對應的值所有的行都進行鎖定,不是鎖定某一更改的行。

針對與某個bitmap索引,每一行都有一個對應的值來標識該行數據是否滿足索引要求

存儲如下:

col_valuerow1row2row3row4row5row6row7
M1000111
F0111000

針對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方式存儲有下面三部分組成:

  1. 每個索引值以索引鍵值開頭

  2. 每個範圍以rowid最小值和最大值標誌

  3. 每個範圍內的rowid的位圖值 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章