數據結構-索引-理論

數據結構-索引-理論

理論部分摘錄自百度百科和網絡。

一、理論

(一)索引的定義

什麼是索引?

1、索引

索引是爲了加速對錶中數據行的檢索而創建的一種分散的存儲結構。

索引已經成爲關係數據庫非常重要的部分。它們被用作包含所關心數據的表指針。

通過一個索引,能從表中直接找到一個特定的記錄,而不必連續順序掃描這個表,一次一個地去查找。

對於大的表,索引是必要的。沒有索引,要想得到一個結果要等好幾個小時、好幾天,而不是幾秒鐘。

在關係數庫中,索引是一種單獨的、物理的對數據庫表中一列或多列的值進行排序的一種存儲結構,它是某個表中一列或若干列值的集合和相應的指向表中物理標識這些值的數據頁的邏輯指針清單。索引的作用相當於圖書的目錄,可以根據目錄中的頁碼快速找到所需的內容。

索引提供指向存儲在表的指定列中的數據值的指針,然後根據您指定的排序順序對這些指針排序。數據庫使用索引以找到特定值,然後順指針找到包含該值的行。這樣可以使對應於表的SQL語句執行得更快,可快速訪問數據庫表中的特定信息。

當表中有大量記錄時,若要對錶進行查詢,第一種搜索信息方式是全表搜索,是將所有記錄一一取出,和查詢條件進行一一對比,然後返回滿足條件的記錄,這樣做會消耗大量數據庫系統時間,並造成大量磁盤I/O操作;第二種就是在表中建立索引,然後在索引中找到符合查詢條件的索引值,最後通過保存在索引中的ROWID(相當於頁碼)快速找到表中對應的記錄。

索引(在 MySQL 中也叫“鍵key”)是存儲引擎快速找到記錄的一種數據結構。——《高性能MySQL》

索引是表的目錄,在查找內容之前可以先在目錄中查找索引位置,以此快速定位查詢數據。對於索引,會保存在額外的文件中。索引,是數據庫中專門用於幫助用戶快速查詢數據的一種數據結構。

2、Oracle索引概念

在oracle中,索引是一種供服務器在表中快速查找一個行的數據庫結構。在數據庫中建立索引主要有以下作用。
  (1)快速存取數據。
  (2)既可以改善數據庫性能,又可以保證列值的唯一性。
  (3)實現表與表之間的參照完整性
  (4)在使用orderby、groupby子句進行數據檢索時,利用索引可以減少排序和分組的時間。

3、Mysql索引概念

MySQL索引的建立對於MySQL的高效運行是很重要的,索引可以大大提高MySQL的檢索速度。

打個比方,如果合理的設計且使用索引的MySQL是一輛蘭博基尼的話,那麼沒有設計和使用索引的MySQL就是一個人力三輪車。

拿漢語字典的目錄頁(索引)打比方,我們可以按拼音、筆畫、偏旁部首等排序的目錄(索引)快速查找到需要的字。

索引分單列索引和組合索引。單列索引,即一個索引只包含單個列,一個表可以有多個單列索引,但這不是組合索引。組合索引,即一個索引包含多個列。

創建索引時,你需要確保該索引是應用在 SQL 查詢語句的條件(一般作爲 WHERE 子句的條件)。

實際上,索引也是一張表,該表保存了主鍵與索引字段,並指向實體表的記錄。

上面都在說使用索引的好處,但過多的使用索引將會造成濫用。因此索引也會有它的缺點:雖然索引大大提高了查詢速度,同時卻會降低更新表的速度,如對錶進行INSERT、UPDATE和DELETE。因爲更新表時,MySQL不僅要保存數據,還要保存一下索引文件。

建立索引會佔用磁盤空間的索引文件。

(二)索引的作用

在數據庫系統中建立索引主要有以下作用:

(1)快速取數據;

(2)保證數據記錄的唯一性;

(3)實現表與表之間的參照完整性;

(4)在使用ORDER by、group by子句進行數據檢索時,利用索引可以減少排序和分組的時間。

(三)索引的優缺點

1、優點

(1)大大加快數據的檢索速度;

(2)創建唯一性索引,保證數據庫表中每一行數據的唯一性;

(3)加速表和表之間的連接;

(4)在使用分組和排序子句進行數據檢索時,可以顯著減少查詢中分組和排序的時間。

2、缺點

(1)索引需要佔物理空間。

(2)當對錶中的數據進行增加、刪除和修改的時候,索引也要動態的維護,降低了數據的維護速度。

索引的缺點是創建和維護索引需要耗費時間

索引可以提高查詢速度,會減慢寫入速度

索引並不是越多越好,索引固然可以提高相應的 select 的效率,但同時也降低了 insert 及 update 的效率,因爲 insert 或 update 時有可能會重建索引,所以怎樣建索引需要慎重考慮,視具體情況而定。

一個表的索引數最好不要超過6個,若太多則應考慮一些不常使用到的列上建的索引是否有必要。

(四)索引的類型

1、索引分類

(1)普通索引

最基本的索引類型,沒有唯一性之類的限制。

(2)唯一索引

唯一索引是不允許其中任何兩行具有相同索引值的索引。

當現有數據中存在重複的鍵值時,大多數數據庫不允許將新創建的唯一索引與表一起保存。數據庫還可能防止添加將在表中創建重複鍵值的新數據。例如,如果在 employee 表中職員的姓 (lname) 上創建了唯一索引,則任何兩個員工都不能同姓。

對某個列建立UNIQUE索引後,插入新記錄時,數據庫管理系統會自動檢查新紀錄在該列上是否取了重複值,在CREATE TABLE 命令中的UNIQE約束將隱式創建UNIQUE索引。

(3)主鍵索引

簡稱爲主索引,數據庫表中一列或列組合(字段)的值唯一標識表中的每一行。該列稱爲表的主鍵。

在數據庫關係圖中爲表定義主鍵將自動創建主鍵索引,主鍵索引是唯一索引的特定類型。該索引要求主鍵中的每個值都唯一。當在查詢中使用主鍵索引時,它還允許對數據的快速訪問。

提示儘管唯一索引有助於定位信息,但爲獲得最佳性能結果,建議改用主鍵索引。

(4)聚集索引

也稱爲聚簇索引,在聚集索引中,表中行的物理順序與鍵值的邏輯(索引)順序相同。一個表只能包含一個聚集索引, 即如果存在聚集索引,就不能再指定CLUSTERED 關鍵字。

索引不是聚集索引,則表中行的物理順序與鍵值的邏輯順序不匹配。與非聚集索引相比,聚集索引通常提供更快的數據訪問速度。聚集索引更適用於對很少對基表進行增刪改操作的情況。

如果在表中創建了主鍵約束,SQL Server將自動爲其產生唯一性約束。在創建主鍵約束時,指定了CLUSTERED關鍵字或乾脆沒有制定該關鍵字,SQL Sever將會自動爲表生成唯一聚集索引。

(5)非聚集索引

也叫非簇索引,在非聚集索引中,數據庫表中記錄的物理順序與索引順序可以不相同。

一個表中只能有一個聚集索引,但表中的每一列都可以有自己的非聚集索引。

如果在表中創建了主鍵約束,SQL Server將自動爲其產生唯一性約束。在創建主鍵約束時,如果制定CLUSTERED關鍵字,則將爲表產生唯一聚集索引。

(6)候選索引

與主索引一樣要求字段值的唯一性,並決定了處理記錄的順序。在數據庫和自由表中,可以爲每個表建立多個候選索引。

(7)HASH索引

HASH索引可能是訪問數據庫中數據的最快方法,但它也有自身的缺點。集羣鍵上不同值的數目必須在創建HASH集羣之前就要知道。需要在創建HASH集羣的時候指定這個值。使用HASH索引必須要使用HASH集羣。

2、MySQL索引分類

(1)主鍵索引:加速查詢 + 列值唯一(不可以有null)+ 表中只有一個

(2)唯一索引:加速查詢 + 列值唯一(可以有null)

(3)普通索引:僅加速查詢

(4)組合索引:多列值組成一個索引,專門用於組合搜索,其效率大於索引合併

(5)全文索引:對文本的內容進行分詞,進行搜索

3、Oracle索引分類

  (1)B*樹索引的存儲結構類似書的索引結構,有分支和葉兩種類型的存儲數據塊,分支塊相當於書的大目錄,葉塊相當於索引到的具體的書頁。Oracle用B*樹機制存儲索引條目,以保證用最短路徑訪問鍵值。默認情況下大多使用B*樹索引,該索引就是通常所見的唯一索引、逆序索引。
  (2)位圖索引存儲主要用於節省空間,減少oracle對數據塊的訪問。它採用位圖偏移方式來與表的行ID號對應,採用位圖索引一般是重複值太多的表字段。位圖索引之所以在實際密集型OLTP(聯機事物處理)中用的比較少,是因爲OLTP會對錶進行大量的刪除、修改、新建操作。Oracle每次進行操作都會對要操作的數據塊加鎖。以防止多人操作容易產生的數據庫鎖等待甚至死鎖現象。在OLAP(聯機分析處理)中應用位圖有優勢,因爲OLAP中大部分是對數據庫的查詢操作,而且一般採用數據倉庫技術,所以大量數據採用位圖索引節省空間比較明顯。當創建表的命令中包含有唯一性關鍵字時,不能創建位圖索引,創建全局分區索引時也不能用位圖索引。
  • 索引按功能和索引對象分還有以下類型。
  (1)唯一索引意味着不會有兩行記錄相同的索引鍵值。唯一索引表中的記錄沒有RowID,不能再對其建立其他索引。在oracle10g中,要建立唯一索引,必須在表中設置主關鍵字,建立了唯一索引的表只按照該唯一索引結構排序。
  (2)非唯一索引不對索引列的值進行唯一性限制。
  (3)分區索引是指索引可以分散地存在於多個不同的表空間中,其優點是可以提高數據查詢的效率。
  (4)未排序索引也稱爲正向索引。Oracle10g數據庫中的行是按升序排序的,創建索引時不必指定對其排序而使用默認的順序。
  (5)逆序索引也稱反向索引。該索引同樣保持列按順序排列,但是顛倒已索引的每列的字節。
  (6)基於函數的索引是指索引中的一列或者多列是一個函數或者表達式,索引根據函數或表達式計算索引列的值。可以將基於函數的索引建立創建成位圖索引。
  另外,按照索引所包含的列數可以把索引分爲單列索引和複合索引。索引列只有一列的索引爲單列索引,對多列同時索引稱爲複合索引。

(五)如何設計索引

1、索引設計的原則

(1)適合索引的列是出現在where子句中的列,或者連接子句中指定的列

(2)基數較小的類,索引效果較差,沒有必要在此列建立索引

(3)使用短索引,如果對長字符串列進行索引,應該指定一個前綴長度,這樣能夠節省大量索引空間

(4)不要過度索引。索引需要額外的磁盤空間,並降低寫操作的性能。在修改表內容的時候,索引會進行更新甚至重構,索引列越多,這個時間就會越長。所以只保持需要的索引有利於查詢即可。

2、索引選取類型

(1)越小的數據類型通常更好:越小的數據類型通常在磁盤、內存和CPU緩存中都需要更少的空間,處理起來更快。

(2)簡單的數據類型更好:整型數據比起字符,處理開銷更小,因爲字符串的比較更復雜。

(3)儘量避免NULL:應該指定列爲NOT nuLL,在MySQL中, 含有空值的列很難進行查詢優化,因爲它們使得索引、索引的統計信息以及比較運算更加複雜

3、什麼場景不適合創建索引

第一,對於那些在查詢中很少使用或者參考的列不應該創建索引。這是因 爲,既然這些列很少使用到,因此有索引或者無索引,並不能提高查詢速度。相反,由於增加了索引,反而降低了系統的維護速度和增大了空間需求。

第二,對於那 些只有很少數據值的列也不應該增加索引。因爲本來結果集合就是相當於全表查詢了,所以沒有必要。這是因爲,由於這些列的取值很少,例如人事表的性別列,在查詢的結果中,結果集的數據行佔了表中數據行的很大比 例,即需要在表中搜索的數據行的比例很大。增加索引,並不能明顯加快檢索速度。

第三,對於那些定義爲text, image和bit數據類型的列不應該增加索引。這是因爲,這些列的數據量要麼相當大,要麼取值很少。

第四,當修改性能遠遠大於檢索性能時,不應該創建索 引。這是因爲,修改性能和檢索性能是互相矛盾的。當增加索引時,會提高檢索性能,但是會降低修改性能。當減少索引時,會提高修改性能,降低檢索性能。因 此,當修改性能遠遠大於檢索性能時,不應該創建索引。

第五,不會出現在where條件中的字段不該建立索引。

4、什麼樣的字段適合創建索引

1、表的主鍵、外鍵必須有索引;外鍵是唯一的,而且經常會用來查詢

2、數據量超過300的表應該有索引;

3、經常與其他表進行連接的表,在連接字段上應該建立索引;經常連接查詢,需要有索引

4、經常出現在Where子句中的字段,加快判斷速度,特別是大表的字段,應該建立索引,建立索引,一般用在select ……where f1 and f2 ,我們在f1或者f2上建立索引是沒用的。只有兩個使用聯合索引纔能有用

5、經常用到排序的列上,因爲索引已經排序。

6、經常用在範圍內搜索的列上創建索引,因爲索引已經排序了,其指定的範圍是連續的

(六)注意事項

並非所有的數據庫都以相同的方式使用索引。作爲通用規則,只有當經常查詢索引列中的數據時,才需要在表上創建索引。索引佔用磁盤空間,並且降低添加、刪除和更新行的速度。如果應用程序非常頻繁地更新數據或磁盤空間有限,則可能需要限制索引的數量。在表較大時再建立索引,表中的數據越多,索引的優越性越明顯。

可以基於數據庫表中的單列或多列創建索引。多列索引使您可以區分其中一列可能有相同值的行。

如果經常同時搜索兩列或多列或按兩列或多列排序時,索引也很有幫助。例如,如果經常在同一查詢中爲姓和名兩列設置判據,那麼在這兩列上創建多列索引將很有意義。

確定索引的有效性:

檢查查詢的 WHERE 和 JOIN 子句。在任一子句中包括的每一列都是索引可以選擇的對象。

對新索引進行試驗以檢查它對運行查詢性能的影響。

考慮已在表上創建的索引數量。最好避免在單個表上有很多索引。

檢查已在表上創建的索引的定義。最好避免包含共享列的重疊索引。

檢查某列中唯一數據值的數量,並將該數量與表中的行數進行比較。比較的結果就是該列的可選擇性,這有助於確定該列是否適合建立索引,如果適合,確定索引的類型。、

(七)索引的數據結構:B-Tree和B+Tree

1、B-Tree和B+Tree

MySQL索引背後的數據結構及算法原理

2、爲什麼要選擇B-Tree和B+Tree作爲索引的數據結構

是什麼影響了數據庫索引選型?

(八)索引的實現原理:MyISAM和InnoDB

索引實現原理

(九)索引優化

MySQL——索引優化實戰

MySQL——優化ORDER BY語句

MySQL——優化嵌套查詢和分頁查詢

二、差異比較

待補充。

(一)MySQL

(二)Oracle

三、查漏補缺

待補充。

四、總結

五、參考

《高性能MySQL》

《深入淺出MySQL》

索引

數據庫索引

Oracle索引

隨筆分類 - MySQL

mysql索引的新手入門詳解

CodingLabs

各種Oracle索引類型介紹

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