索引與視圖

索引

索引的概念:

在關係型數據庫中,索引是對數據庫表中一列或多列的值進行排序後單獨的物理存儲結構。數據庫

在Oracle中,索引是除了表以外的另外一種重要的數據庫方案對象。索引的主要用途是提升數據表的查詢速度,它能夠獨立於表進行存儲。經過在表中創建索引,能夠在索引中找到符合查詢條件的索引值,而後再經過保存在索引中的 ROWID 快速找到表中對應的記錄。express

  • 索引是一個單獨的物理存儲結構,能夠有本身的存儲空間,沒必要與相關聯的表處在同一個表空間中。
  • 索引由表中一列或多列值的集合和這些值所在的 ROWID(表中數據行的惟一性標識,它不能指示出行的物理位置,但能夠用來定位行) 組成。
  • 在Oracle系統中,對索引的應用和維護是自動完成的。
  • 使用索引的好處:安全

    • 建立惟一索引後能夠保證每行數據的惟一性。
    • 能夠加速檢索數據的速度。
    • 多表查詢時,能夠加速表之間的鏈接。
    • 明顯減小分組和排序的時間。
  • 創建索引後的不足:函數

    • 建立和維護索引須要消耗額外的時間和空間。
    • 對錶中數據進行DML操做時,也要動態維護索引,下降了處理數據的速度。
  • 適合建立索引的字段應具有如下特徵:性能

    • 取值範圍較大的字段。
    • Null值較多的字段。
    • 常常做爲查詢或鏈接條件的字段。
    • 常常須要排序的字段。
  • 不適合創建索引的表、字段具有如下特徵:學習

    • 較小的表。
    • 常常更新的表。
    • 不常做爲查詢條件或鏈接條件的字段。
索引的類型:

Oracle能夠建立多種不一樣類型的索引,以適應各類表的特色。常見的索引類型包括Balance-tree索引、位圖索引、反向鍵索引、基於函數的索引、全局索引和局部索引等。優化

Balance-tree索引:
  • Balance-tree索引是最多見的索引結構。
  • Oracle採用的默認索引類型。
  • 其組織結構相似於一棵樹,其中的主要數據都集中在葉子結點上。
  • 各葉子結點中包括:索引列的值和數據表中對應的 ROWID。
  • 特別適用於檢索高基數數據列,即所查詢的列的惟一性索引值的個數與其數據行記錄數之比接近於1:1的狀況(被索引的列值基本沒有相同的值)。【我理解爲該列數據多樣化】
  • Balance-tree索引的優勢以下:spa

    • Balance-tree中全部葉子結點基本都處於同一深度,查詢時消耗的時間基本相同。
    • Balance-tree的索引結構是自動保持平衡的。
    • Balance-tree爲必定範圍的查詢提供了極好的性能,包括精準匹配和範圍查找。
    • Balance-tree的插入、更新和刪除效率高。
    • Balance-tree索引的性能不會隨着表大小的增加而下降。
  • Balance-tree索引的侷限性:當數據檢索的範圍超過表的10%時就再也不適合使用Balance-tree索引。
位圖索引:
  • 位圖索引也採用Balance-tree索引,只是索引值所有集中在葉子結點。
  • 位圖中的每個位對應一個 ROWID。(例如某一位的值爲1,則對應ROWID的行包含該索引鍵值)這種方式叫作位圖的映射功能,即將數據位的位值轉化爲實際的ROWID。
  • 位圖索引適用於檢索👉不多有惟一值的列,例如性別。
  • 位圖索引的使用狀況:若是列中惟一值的個數與表中總的記錄行數之比少於1%,則該列可採用位圖索引。【我理解爲該列數據種類較爲單一】
  • 位圖索引中再也不記錄ROWID和鍵值,而是將每一個索引值做爲一列,用1和0表示該行中是否包含該索引值。
  • 因爲位圖索引的行順序與原表的行順序一致,所以給定表的關鍵起始和終止ROWID,能夠在查詢過程當中對應計算出行的原始物理位置。
反向鍵索引:
  • 反向鍵索引是一種特殊類型的Balance-tree索引,與常規Balance-tree索引的存儲結構相同。
  • 特別適合基於有序數列創建的索引。
  • 反向鍵索引是爲了不常規Balance-tree索引的歪樹現象時使用的,它會對用戶輸入的索引鍵值的字節進行反向處理,使其變爲非遞增狀態,這樣在葉子結點的分佈就會比較均勻。
基於函數的索引:
  • 基於函數的索引也是普通的Balance-tree索引,但它是基於表中某些字段的函數創建的,並不創建在某些字段上。
  • 基於函數的索引是爲了不用戶在使用基於函數的WHERE搜索條件時,Oracle會被迫進行全表搜索下降效率的狀況下使用。
  • 基於函數的索引有兩個主要做用:日誌

    • 只對限定的行建立索引,節約空間,提升檢索速度。
    • 優化WHERE子句中使用了函數的SQL語句。
全局索引和局部索引:

爲了便於管理和維護表,Oracle容許將表按照range、hash、list進行分區。表分區後,其上的索引也和普通的索引有區別。分區後的表能夠創建3種類型的索引:局部分區索引、全局分區索引和全局非分區索引。
局部分區索引:code

  • 將表分區後,爲每一個分區單獨創建的索引稱爲局部分區索引。
  • 每一個局部分區索引是針對單個分區的,每一個分區索引只指向一個表分區,它們互相獨立。
  • 便於管理,多用於數據倉庫環境中。

圖片.png
先進行表分區,再爲每一個分區單獨創建索引。

全局分區索引:

  • 全局分區索引是對整個分區表創建索引,而後再由Oracle對索引進行分區。
  • 全局分區索引的各個分區之間並不是相互獨立,索引分區與分區表之間也並不是一對一關係。

圖片.png
直接對整個分區表創建索引,再對這個索引進行分區。

全局非分區索引:

  • 全局非分區索引就是對整個分區創建索引,但未對索引進行分區,一個索引對應着表的全部分區。

圖片.png
直接對整個分區創建索引,不對這個索引進行分區。

建立索引:
CREATE [UNIQUE | BITMAP] INDEX [schema.]<index_name>
ON [schema.]<table_name>
(<column_name> | <expression> ASC| DESC,
<column_name>|<expression> ASC| DESC,…)
[TABLESPACE <tablespace_name>]
[STORAGE(<storage_settings>)]
[LOGGING | NOLOGGING]
[NOSORT | REVERSE]
[PARTITION | GLOBAL PARTITION<partition_setting>]
  • UNIQUE | BITMAP:UNIQUE表示建立的索引是惟一索引,要求建立索引的表達式或字段值必須惟一,不可重複,建立主鍵約束或惟一約束時系統自動建立對應的惟一索引;BITMAP表示建立的索引是位圖索引。當省略前面這兩個關鍵字時,默認建立的索引是能夠重複的Balance-tree索引。
  • [schema.] <table_name>:該子句指出了建立索引的表,其中schema指明表所屬的方案名,table_name指表名。
  • <column_name> | <expression> ASC | DESC:該子句指出了建立索引的列,其中column_name表示基於表中的字段建立索引,expression表示基於某個表達式建立索引。ASC表示建立的索引爲升序排列,DESC表示建立的索引爲降序排列。建立索引時能夠指定多個字段或多個表達式,之間用逗號隔開便可。
  • TABLESPACE:表示建立索引時能夠爲索引指定單獨的表空間,能夠不與相關聯的表位於同一個表空間中。(當索引與所對應的表處於不一樣的表空間時,能夠得到更好的性能
  • STORAGE:該子句設置存儲索引的表空間的存儲特性。
  • LOGGING | NOLOGGING:表示在建立索引時是否建立相應的日誌記錄。
  • NOSORT | REVERSE:NOSORT表示建立的索引與表中的順序相同,再也不對索引進行排序。使用NOSORT子句的目的是節省建立索引的時間和空間。REVERSE表示以相反的順序存儲索引值,即建立的索引是反向鍵索引。
  • PARTITION | GLOBAL PARTITION:PARTITION表示創建分區索引;GLOBAL PARTITION 表示創建全局分區索引;當省略該子句時表示創建非分區索引。

建立索引時須要適當的權限才能夠完成。若是用戶在本身的方案中建立索引,則應該具備CREATE INDEX系統權限,若是在其餘用戶的方案中建立索引,則必須具備CREATE ANY INDEX系統權限。

建立Balance-tree索引:
  • Balance-tree索引是建立索引時的默認類型。
  • 當用戶爲表建立主鍵約束時,系統自動爲該列建立一個Balance-tree索引。
  • 當使用CREATE INDEX命令建立Balance-tree索引時,若包含UNIQUE關鍵字,則表示建立一個具備惟一值的Balance-tree索引。
  • 在Oracle中能夠建立基於多個字段的索引,稱爲「複合索引」,其中各個字段的順序隨意,通常將經常使用字段前置。
  • 在查詢時,若是WHERE子句中只包含複合索引的第一個字段,那麼只有前置的第一個索引會提升查詢速度,由於是前置字段。
建立位圖索引:
  • 當表中某一個字段的惟一值的個數比較少(基數小)時,在該字段上創建位圖索引比較合適。
  • 在建立位圖索引時,必須顯式指定BITMAP關鍵字。
  • 因爲創建位圖索引的字段有許多重複值。所以位圖索引不能是惟一索引。
建立反向鍵索引:
  • 反向鍵索引的本質也是一個Balance-tree索引,但它不一樣於通常的Balance-tree索引。
  • 若是創建索引的字段值順序增加或降低,那麼使用反向鍵索引能夠避免「歪樹」現象的產生。
  • 反向鍵索引適用於嚴格排序的列,對鍵值的反向操做由系統自動處理。
  • 建立反向索引時必須指定關鍵字REVERSE。
建立基於函數的索引:
  • 在DML操做時若是常用某個表達式做爲條件,就能夠創建基於該函數的索引。
  • 在建立基於函數的索引時,Oracle首先對包含索引列的函數或表達式進行求值,而後對這些值進行排序,最後再存儲到索引中。
  • 基於函數的索引能夠是普通的Balance-tree索引,也能夠是位圖索引,這與函數中字段的取值特色有關係。
應用索引:

補充:Oracle對查詢語句的執行過程包括解析代碼、優化代碼、生成代碼和執行代碼。

  • 解析代碼:是指Oracle對用戶提交的查詢語句進行語法檢查和語義分析等操做,查詢語句將變成可運行的。
  • 優化代碼:是指找到執行用戶查詢的最佳路徑。這一步中Oracle可能會使用兩種優化器,一種是基於規則的優化器(Rule Based Optimizer,RBO),另外一種是基於開銷的優化器(Cost Based Optimizer,CBO)。
  • 在優化器選擇了最佳路徑後,Oracle會將其格式化爲實際的執行方案,而後由系統的執行引擎去執行,也就是完成了生成代碼和執行代碼的過程。

Oracle中索引的應用是由優化器決定的,優化器根據優化的結果自動選擇合適的索引來使用。
Oracle在執行命令時,在決定是否應用索引時主要和如下兩個因素有關係:

  • 數據表的大小。當優化器進行全表掃描時,它會一次讀取一批數據塊,而不是一次讀取一個數據塊。假設一個由50個數據塊組成的表,若是優化器一次讀取10個數據塊,則該表須要讀取5次完成全表掃描,因爲索引須要3次讀取,因此這種狀況下優化器會使用索引來完成。可是,當表只有20~30個數據塊時,全表掃描只須要2~3次讀取就能夠完成,這時索引就會下降獲取數據的速度,所以優化器會使用全表掃描,而不使用索引。
  • 用戶獲取記錄的多少。若是用戶查詢須要讀取記錄的個數佔全表的5%~20%或者更多,那麼就會執行全表搜索,而不考慮使用索引。這是由於一個索引項只會指向一個單獨的數據塊,這樣一次只能讀取一個數據塊,若是使用指向許多數據塊的索引,那麼就須要執行大量的單獨數據塊讀取操做。

Oracle中可使用autotrace參數來跟蹤執行查詢操做時索引的使用狀況。
SET AUTOTRACE TRACEONLY;

視圖

視圖的概念:

視圖是Oracle中的數據庫對象,它能夠針對複雜的查詢進行存儲爲數據庫對象,以便往後反覆使用。

  • 視圖是一個邏輯虛擬表。
  • 能夠對試圖執行各類DML操做。
  • 試圖並不在數據庫中真正存儲有數據,它的數據來自定義視圖的查詢所引用的表,且這些數據是在使用視圖時動態生成的。
  • 視圖在數據庫中只對應着一個SELECT語句的定義。
視圖的優勢:
  • 簡化數據,精簡高效。
  • 加強數據的安全性,用戶被限制在數據的任意子集上,進一步增強了數據的安全訪問機制。
  • 定製數據,不一樣用戶可訪問的數據集不一樣。
  • 合併於分割數據,保持表的原有結構關係,從而使外模式保持不變,應用程序能夠經過視圖重載數據。
  • 利用視圖修改源表,動態即時修改。
建立與管理視圖:

視圖中的數據來源於數據源表,所以在建立視圖時用戶應該具備對視圖所引用表的查詢權限。另外,用戶若是在本身的方案下建立視圖,須要具備CREATE VIEW權限;若是在其餘方案下建立視圖,須要具備CREATE ANY VIEW權限。

建立視圖的語法以下:
CREATE [OR REPLACE] [FORCE | NOFORCE] VIEW [schema.] view_name [(column[ ,...n])] AS SELECT_statement [WITH CHECK OPTION | WITH READ ONLY]
  • FORCE | NOFORCE:FORCE表示無論視圖引用的表是否存在,都要強制建立該視圖;NOFORCE表示只有基表存在時,才建立視圖。省略該選項時默認爲NOFORCE。
  • column [ ,...n]:表示視圖中的一組列名,這是爲後面的查詢語句中選擇的列新定義的名字,替表明中原有的列名。
  • SELECT_statement:表示建立視圖的SELECT語句。利用SELECT語句能夠從一個或多個表或者視圖中獲取視圖中的行和列,也可使用UNION關鍵字聯合多個SELECT語句。(視圖可嵌套)
  • WITH CHECK OPTION | WITH READ ONLY:WITH CHECK OPTION表示對視圖進行插入或修改時,新數據必須知足查詢語句中WHERE字句後面的條件;WITH READ ONLY表示視圖是隻讀的。當省略這兩個選項時,新建立的視圖是一個可修改的、對其操做不進行條件檢查的通常視圖。
從新編譯視圖:

建立視圖後,Oracle會驗證視圖的有效性。若是在之後的操做中修改了數據源表的結構,那麼可能會使視圖變爲無效。這時可使用ALTER VIEW命令從新編譯視圖使之有效:

ALTER VIEW view_name COMPILE;
刪除視圖:
DROP VIEW view_name;
建立可更新的視圖:

可更新的視圖是指用戶能夠對視圖執行INSERT、UPDATE、DELETE操做的視圖,利用該類視圖用戶能夠完成對數據源表的修改。
可更新的視圖或視圖的可更新列應具備如下特色:

  • 建立時不能選擇WITH READ ONLY選項。
  • 視圖中的非計算或非聚合運算(即數據源表中的原始字段)才能夠被更新。
  • 視圖的定義中SELECT語句不能包含DISTINCT(去重)關鍵字。
  • 視圖的定義中SELECT語句不能包含集合操做,如UNION、INTERSECT(交集)等。
  • 視圖的定義中SELECT語句不能包含GROUP BY子句和HAVING子句。
  • 用戶必須對視圖的數據源表具備顯示的操做權限。
  • 只有在視圖中可見的行和列才能被修改或刪除。

用戶能夠經過查詢數據字典中的視圖USER_UPDATETABLE_COLUMNS瞭解視圖中的可更新列。


文章根據《Oracle數據庫應用於開發》機械工業出版社 石彥芳、李丹著 一書中總結及補充,僅做本人學習用。
文章中若出現錯誤,請在評論中指出或聯繫我👇
QQ:354008947
Email:354008947@qq.com
幸福至上.png

相關文章
相關標籤/搜索