索引是對資料庫表中一列或多列的值進行排序的一種結構,使用索引可快速訪問資料庫表中的特定資訊。
資料庫索引好比是一本書前面的目錄,能加快資料庫的查詢速度。
例如這樣乙個查詢:select * from table1 where id=44。如果沒有索引,必須遍歷整個表,直到id等於44的這一行被找到為止;有了索引之後(必須是在id這一列上建立的索引),直接在索引裡面找44(也就是在id這一列找),就可以得知這一行的位置,也就是找到了這一行。可見,索引是用來定位的。
索引分為
聚簇索引
和非聚簇索引
兩種,聚簇索引 是按照資料存放的物理位置為順序的,而非聚簇索引就不一樣了;聚簇索引能提高多行檢索的速度,而非聚簇索引對於單行的檢索很快。
我們通過乙個簡單的例子來開始教程,解釋為什麼我們需要資料庫索引。假設我們有乙個資料庫表 employee, 這個表有三個字段(列)分別是 employee_name、employee_age 和employee_address。假設表employee 有上千行資料。
現在假設我們要從這個表中查詢出所有名字是『jesus』的雇員資訊。我們決定使用下面的查詢語句:
select * from employee
where employee_name = 'jesus'
如果表中沒有所以會發生什麼?
一旦我們執行這個查詢,在查詢名字為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那麼靈活
還有什麼其他型別的索引?
索引是怎麼提公升效能的?
因為索引基本上是用來儲存列值的資料結構,這使查詢這些列值更加快速。如果索引使用最常用的資料結構-b-tree-那麼其中的資料是有序的。有序的列值可以極大的提公升效能。下面解釋原因。
假設我們在 employee_name這一列上建立乙個b-tree索引。這意味著當我們用之前的sql查詢姓名是『jesus』的雇員時,不需要再掃瞄全表。而是用索引查詢去查詢名字為『jesus』的雇員,因為索引已經按照按字母順序排序。索引已經排序意味著查詢乙個名字會快很多,因為名字少字母為『j』的員工都是排列在一起的。另外重要的一點是,索引同時儲存了表中相應行的指標以獲取其他列的資料。
資料庫索引裡究竟存的是什麼?
你現在已經知道資料庫索引是建立在表的某列上的,並且儲存了這一列的所有值。但是,需要理解的重點是資料庫索引並不儲存這個表中其他列(字段)的值。舉例來說,如果我們在employee_name列建立索引,那麼列employee_age和employee_address上的值並不會儲存在這個索引當中。如果我們確實把其他所有欄位也儲存在個這個索引中,那就成了拷貝一整張表做為索引-這樣會占用太大的空間而且會十分低效。
索引儲存了指向表中某一行的指標
如果我們在索引裡找到某一條記錄作為索引的列的值,如何才能找到這一條記錄的其它值呢?這是很簡單 - 資料庫索引同時儲存了指向表中的相應行的指標。指標是指一塊記憶體區域, 該記憶體區域記錄的是對硬碟上記錄的相應行的資料的引用。因此,索引中除了儲存列的值,還儲存著乙個指向在行資料的索引。也就是說,索引中的employee_name這列的某個值(或者節點)可以描述為 (「jesus」, 0x82829), 0x82829 就是包含 「jesus」那行資料在硬碟上的位址。如果沒有這個引用,你就只能訪問到乙個單獨的值(「jesus」),而這樣沒有意義,因為你不能獲取這一行記錄的employee的其他值-例如位址(address)和年齡(age)。
資料庫怎麼知道什麼時候使用索引?
你能強制資料庫使用索引嗎?
通常來說, 你不會告訴資料庫什麼時候使用索引 - 資料庫自己決定。然而,值得注意的是在大多數資料庫中(像oracle 和 mysql), 你實際上可以制訂你想要使用的索引。
如何在使用sql建立索引:
之前的例子中,在employee_name列上建立索引的sql如下:
create
index name_index
on employee (employee_name)
如何建立聯合索引
我們可以在雇員表上建立兩個列的聯合索引,sql如下:
create
index name_index
on employee (employee_name, employee_age)
把資料庫索引模擬成什麼比較好呢?
使用資料庫索引會有什麼代價?
那麼,使用資料庫索引有什麼缺點呢?其一,索引會占用空間 - 你的表越大,索引占用的空間越大。其二,效能損失(主要值更新操作),當你在表中新增、刪除或者更新行資料的時候, 在索引中也會有相同的操作。記住:建立在某列(或多列)索引需要儲存該列最新的資料。
基本原則是只如果表中某列在查詢過程中使用的非常頻繁,那就在該列上建立索引。
資料庫索引到底是什麼,是怎樣工作的?
我們通過乙個簡單的例子來開始教程,解釋為什麼我們需要資料庫索引。假設我們有乙個資料庫表 employee,這個表有三個字段 列 分別是 employee name employee age 和employee address。假設表employee 有上千行資料。現在假設我們要從這個表中查詢出所有名...
資料庫索引到底是什麼,是怎樣工作的?
資料庫索引到底是什麼,是怎樣工作的?我們通過乙個簡單的例子來開始教程,解釋為什麼我們需要資料庫索引。假設我們有乙個資料庫表 employee,這個表有三個字段 列 分別是 employee name employee age 和employee address。假設表employee 有上千行資料。...
資料庫索引到底是什麼,是怎樣工作的?
我們通過乙個簡單的例子來開始教程,解釋為什麼我們需要資料庫索引。假設我們有乙個資料庫表 employee,這個表有三個字段 列 分別是 employee name employee age 和employee address。假設表employee 有上千行資料。現在假設我們要從這個表中查詢出所有名...