資料庫索引原理

2021-08-28 13:13:59 字數 4282 閱讀 5694

說白了,索引問題就是乙個查詢問題。。。

資料庫索引,是資料庫管理系統中乙個排序的資料結構,以協助快速查詢、更新資料庫表中資料。索引的實現通常使用b樹及其變種b+樹

在資料之外,資料庫系統還維護著滿足特定查詢演算法的資料結構,這些資料結構以某種方式引用(指向)資料,這樣就可以在這些資料結構上實現高階查詢演算法。這種資料結構,就是索引。

為表設定索引要付出代價的:一是增加了資料庫的儲存空間,二是在插入和修改資料時要花費較多的時間(因為索引也要隨之變動)。

上圖展示了一種可能的索引方式。左邊是資料表,一共有兩列七條記錄,最左邊的是資料記錄的實體地址(注意邏輯上相鄰的記錄在磁碟上也並不是一定物理相鄰的)。為了加快col2的查詢,可以維護乙個右邊所示的二叉查詢樹,每個節點分別包含索引鍵值和乙個指向對應資料記錄實體地址的指標,這樣就可以運用二叉查詢在o(log2n)的複雜度內獲取到相應資料。

建立索引可以大大提高系統的效能。

第一,通過建立唯一性索引,可以保證資料庫表中每一行資料的唯一性。

第二,可以大大加快資料的檢索速度,這也是建立索引的最主要的原因。

第三,可以加速表和表之間的連線,特別是在實現資料的參考完整性方面特別有意義。

第四,在使用分組和排序子句進行資料檢索時,同樣可以顯著減少查詢中分組和排序的時間。

第五,通過使用索引,可以在查詢的過程中,使用優化隱藏器,提高系統的效能。 

也許會有人要問:增加索引有如此多的優點,為什麼不對錶中的每乙個列建立乙個索引呢?因為,增加索引也有許多不利的方面。

第一,建立索引和維護索引要耗費時間,這種時間隨著資料量的增加而增加。

第二,索引需要佔物理空間,除了資料表佔資料空間之外,每乙個索引還要佔一定的物理空間,如果要建立聚簇索引,那麼需要的空間就會更大。

第三,當對表中的資料進行增加、刪除和修改的時候,索引也要動態的維護,這樣就降低了資料的維護速度。

索引是建立在資料庫表中的某些列的上面。在建立索引的時候,應該考慮在哪些列上可以建立索引,在哪些列上不能建立索引。一般來說,應該在這些列上建立索引:

在經常需要搜尋的列上,可以加快搜尋的速度;

在作為主鍵的列上,強制該列的唯一性和組織表中資料的排列結構;

在經常用在連線的列上,這些列主要是一些外來鍵,可以加快連線的速度;

在經常需要根據範圍進行搜尋的列上建立索引,因為索引已經排序,其指定的範圍是連續的;

在經常需要排序的列上建立索引,因為索引已經排序,這樣查詢可以利用索引的排序,加快排序查詢時間;

在經常使用在where子句中的列上面建立索引,加快條件的判斷速度。

同樣,對於有些列不應該建立索引。一般來說,不應該建立索引的的這些列具有下列特點:

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

第二,對於那些只有很少資料值的列也不應該增加索引。這是因為,由於這些列的取值很少,例如人事表的性別列,在查詢的結果中,結果集的資料行佔了表中資料行的很大比例,即需要在表中搜尋的資料行的比例很大。增加索引,並不能明顯加快檢索速度。

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

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

根據資料庫的功能,可以在資料庫設計器中建立三種索引:唯一索引、主鍵索引和聚集索引

唯一索引是不允許其中任何兩行具有相同索引值的索引。 當現有資料中存在重複的鍵值時,大多數資料庫不允許將新建立的唯一索引與表一起儲存。資料庫還可能防止新增將在表中建立重複鍵值的新資料。例如,如果在employee表中職員的姓(lname)上建立了唯一索引,則任何兩個員工都不能同姓。

主鍵索引資料庫表經常有一列或列組合,其值唯一標識表中的每一行。該列稱為表的主鍵。 在資料庫關係圖中為表定義主鍵將自動建立主鍵索引,主鍵索引是唯一索引的特定型別。該索引要求主鍵中的每個值都唯一。當在查詢中使用主鍵索引時,它還允許對資料的快速訪問。

聚集索引在聚集索引中,表中行的物理順序與鍵值的邏輯(索引)順序相同。乙個表只能包含乙個聚集索引

如果某索引不是聚集索引,則表中行的物理順序與鍵值的邏輯順序不匹配。與非聚集索引相比,聚集索引通常提供更快的資料訪問速度

由於儲存介質的特性,磁碟本身訪問就比主存慢很多,再加上機械運動耗費,磁碟的訪問速度往往是主存的幾百分分之一,因此為了提高效率,要儘量減少磁碟i/o。為了達到這個目的,磁碟往往不是嚴格按需讀取,而是每次都會預讀,即使只需要乙個位元組,磁碟也會從這個位置開始,順序向後讀取一定長度的資料放入記憶體。這樣做的理論依據是電腦科學中著名的區域性性原理當乙個資料被用到時,其附近的資料也通常會馬上被使用。程式執行期間所需要的資料通常比較集中。(可查閱作業系統相關的書)

由於磁碟順序讀取的效率很高(不需要尋道時間,只需很少的旋轉時間),因此對於具有區域性性的程式來說,預讀可以提高i/o效率。

預讀的長度一般為頁(page)的整倍數。頁是計算機管理儲存器的邏輯塊,硬體及作業系統往往將主存和磁碟儲存區分割為連續的大小相等的塊,每個儲存塊稱為一頁(在許多作業系統中,頁得大小通常為4k),主存和磁碟以頁為單位交換資料。當程式要讀取的資料不在主存中時,會觸發乙個缺頁異常,此時系統會向磁碟發出讀盤訊號,磁碟會找到資料的起始位置並向後連續讀取一頁或幾頁載入記憶體中,然後異常返回,程式繼續執行。

到這裡終於可以分析為何資料庫索引採用b-/+tree儲存結構了。上文說過資料庫索引是儲存到磁碟的而我們又一般以使用磁碟i/o次數來評價索引結構的優劣。先從b-tree分析,根據b-tree的定義,可知檢索一次最多需要訪問h個節點(根節點常駐記憶體)。資料庫系統的設計者巧妙利用了磁碟預讀原理,將乙個節點的大小設為等於乙個頁,這樣每個節點只需要一次i/o就可以完全載入。為了達到這個目的,在實際實現b-tree還需要使用如下技巧:每次新建節點時,直接申請乙個頁的空間,這樣就保證乙個節點物理上也儲存在乙個頁裡,加之計算機儲存分配都是按頁對齊的,就實現了乙個node只需一次i/o。

b-tree中一次檢索最多需要h次i/o(根節點常駐記憶體),漸進複雜度為o(h)=o(logdn)。一般實際應用中,出度d是非常大的數字,通常超過100,因此h非常小(通常不超過3)。

綜上所述,如果我們採用b-tree儲存結構,搜尋時i/o次數一般不會超過3次,所以用b-tree作為索引結構效率是非常高的。

從上面介紹我們知道,b樹的搜尋複雜度為o(h)=o(logdn),所以樹的出度d越大,深度h就越小,i/o的次數就越少。b+tree恰恰可以增加出度d的寬度,因為每個節點大小為乙個頁大小,所以出度的上限取決於節點內key和data的大小:

dmax=floor(pagesize/(keysize+datasize+pointsize))//floor表示向下取整

由於b+tree內節點去掉了data域,因此可以擁有更大的出度,從而擁有更好的效能。

b-樹和b+樹查詢過程基本一致。如上圖所示,如果要查詢資料項29,那麼首先會把磁碟塊1由磁碟載入到記憶體,此時發生一次io,在記憶體中用二分查詢確定29在17和35之間,鎖定磁碟塊1的p2指標,記憶體時間因為非常短(相比磁碟的io)可以忽略不計,通過磁碟塊1的p2指標的磁碟位址把磁碟塊3由磁碟載入到記憶體,發生第二次io,29在26和30之間,鎖定磁碟塊3的p2指標,通過指標載入磁碟塊8到記憶體,發生第三次io,同時記憶體中做二分查詢找到29,結束查詢,總計三次io。真實的情況是,3層的b+樹可以表示上百萬的資料,如果上百萬的資料查詢只需要三次io,效能提高將是巨大的,如果沒有索引,每個資料項都要發生一次io,那麼總共需要百萬次的io,顯然成本非常非常高。

資料庫 資料庫索引原理

正確的建立合適的索引 是提公升資料庫查詢效能的基礎 4.b tree 在兩大引擎中的體現 5.索引的原則 索引是為了加速對錶中資料行的檢索而建立的一種分散儲存的資料結構。索引能極大的減少儲存引擎需要掃瞄的資料量 索引可以把隨機io變成順序io 索引可以幫助我們在進行分組 排序等操作時,避免使 用臨時...

資料庫原理 索引

一 索引的概念 索引就是加快檢索表中資料的方法。資料庫的索引類似於書籍的索引。在書籍中,索引允許使用者不必翻閱完整個書就能迅速地找到所需要的資訊。在資料庫中,索引也允許資料庫程式迅速地找到表中的資料,而不必掃瞄整個資料庫。二 索引的特點 1.索引可以加快資料庫的檢索速度 2.索引降低了資料庫插入 修...

資料庫索引原理

說白了,索引問題就是乙個查詢問題。資料庫索引,是資料庫管理系統中乙個排序的資料結構,以協助快速查詢 更新資料庫表中資料。索引的實現通常使用b樹及其變種b 樹。在資料之外,資料庫系統還維護著滿足特定查詢演算法的資料結構,這些資料結構以某種方式引用 指向 資料,這樣就可以在這些資料結構上實現高階查詢演算...