我們通過一個簡單的例子來開始教程,解釋為什么我們需要數據庫索引。假設我們有一個數據庫表 Employee, 這個表有三個字段(列)分別是 Employee_Name、Employee_Age 和Employee_Address。假設表Employee 有上千行數據。
如果表中沒有所以會發生什么?
一旦我們運行這個查詢,在查找名字為Jesus的雇員的過程中,究竟會發生什么?數據庫不得不Employee表中的每一行并確定雇員的名字(Employee_Name)是否為 ‘Jesus’。由于我們想要得到每一個名字為Jesus的雇員信息,在查詢到第一個符合條件的行后,不能停止查詢,因為可能還有其他符合條件的行。所以,必須一行一行的查找直到最后一行-這就意味數據庫不得不檢查上千行數據才能找到所以名字為Jesus的雇員。這就是所謂的全表掃描。
數據庫索引是怎樣提升性能的?
你可能會想為如此簡單的事情做全表掃描效率欠佳-數據庫是不是應該更聰明一點呢?這就像用人眼從頭到尾瀏覽整張表-很慢也不優雅(原文:not at all sleek,不知如何翻譯才好)。但是,你可以能根據文章標題已經猜到,這就是索引派上用場的時候。使用索引的全部意義就是通過縮小一張表中需要查詢的記錄/行的數目來加快搜索的速度。
什么是索引?
一個索引是存儲的表中一個特定列的值數據結構(最常見的是B-Tree)。索引是在表的列上創建。所以,要記住的關鍵點是索引包含一個表中列的值,并且這些值存儲在一個數據結構中。請記住記住這一點:索引是一種數據結構 。
什么樣的數據結構可以作為索引?
B-Tree 是最常用的用于索引的數據結構。因為它們是時間復雜度低, 查找、刪除、插入操作都可以可以在對數時間內完成。另外一個重要原因存儲在B-Tree中的數據是有序的。數據庫管理系統(RDBMS)通常決定索引應該用哪些數據結構。但是,在某些情況下,你在創建索引時可以指定索引要使用的數據結構。
哈希表索引是怎么工作的?
哈希表是另外一種你可能看到用作索引的數據結構-這些索引通常被稱為哈希索引。使用哈希索引的原因是,在尋找值時哈希表效率極高。所以,如果使用哈希索引,對于比較字符串是否相等的查詢能夠極快的檢索出的值。例如之前我們討論過的這個查詢(SELECT * FROM Employee WHERE Employee_Name = ‘Jesus’) 就可以受益于創建在Employee_Name 列上的哈希索引。哈系索引的工作方式是將列的值作為索引的鍵值(key),和鍵值相對應實際的值(value)是指向該表中相應行的指針。因為哈希表基本上可以看作是關聯數組,一個典型的數據項就像“Jesus => 0x28939″,而0x28939是對內存中表中包含Jesus這一行的引用。在哈系索引的中查詢一個像“Jesus”這樣的值,并得到對應行的在內存中的引用,明顯要比掃描全表獲得值為“Jesus”的行的方式快很多。
哈希索引的缺點
哈希表是無順的數據結構,對于很多類型的查詢語句哈希索引都無能為力。舉例來說,假如你想要找出所有小于40歲的員工。你怎么使用使用哈希索引進行查詢?這不可行,因為哈希表只適合查詢鍵值對-也就是說查詢相等的查詢(例:like “WHERE name = ‘Jesus’)。哈希表的鍵值映射也暗示其鍵的存儲是無序的。這就是為什么哈希索引通常不是數據庫索引的默認數據結構-因為在作為索引的數據結構時,其不像B-Tree那么靈活
還有什么其他類型的索引?
使用R-Tree作為數據結構的索引通常用來為空間問題提供幫助。例如,一個查詢要求“查詢出所有距離我兩公里之內的星巴克”,如果數據庫表使用R- Tree索引,這類查詢的效率將會提高。
另一種索引是位圖索引(bitmap index), 這類索引適合放在包含布爾值(true 和 false)的列上,但是這些值(表示true或false的值)的許多實例-基本上都是選擇性(selectivity)低的列。