sqlite索引的原理

2022-07-25 04:24:08 字數 3327 閱讀 6685

這篇文章,裡面講到對於乙個41g大小、包含百萬條記錄的資料庫進行查詢操作,如果利用了索引,可以把操作耗時從37s降到0.2s。

那麼什麼是索引呢?利用索引可以加快資料庫查詢操作的原理是什麼呢?

資料庫提供了一種持久化的資料儲存方式,從資料庫中查詢資料庫是乙個基本的操作,查詢操作的效率是很重要的。

對於查詢操作來說,如果被查詢的資料已某種方式組織起來,那麼查詢操作的效率會極大提高。

在資料庫中,一條記錄會有很多列。如果把這些記錄按照列col1以某種資料結構組織起來,那麼列col2一定是亂序的。

因此,資料庫在原始資料之外,維護了滿足特定查詢演算法的資料結構,指向原始資料,稱之為索引

舉例來說,在下面的圖中,資料庫有兩列col1、col2。在儲存時,按照列col1組織各行,比如col1已二叉樹方式組織。如果查詢col1中的某乙個值,利用二叉樹進行二分查詢,不需要遍歷整個資料庫。

這樣一來列col2就是亂序的。為了解決這個問題,為col2建立了索引,即把col2也按照某種資料結構(這裡是二叉樹)組織起來。這樣子查詢列col2時只需要進行二分查詢即可。

由於資料庫是儲存在磁碟上的,因此實現索引用的資料結構會儲存在磁碟上。磁碟的io是需要注意的問題。

二叉樹二叉樹是一種經典的資料結構,但是並不適合進行資料庫索引。

原因在於二叉樹中每乙個節點的度只有2,樹的深度較高。在儲存時,一般乙個節點需要一次磁碟io,樹的深度較高,查詢乙個資料需要的磁碟io次數越高,查詢需要的時間越長。

b樹b樹是二叉樹的變種,主要區別在於每乙個節點的度可以大於2,即每乙個節點可以分很多叉,大大降低了樹的深度。

上面這些特點使得b+樹的深度大大降低,並且實現了對資料的有序組織。

b+樹b+樹是對b樹的擴充套件,特點在於非葉子節點不儲存data,只儲存key。如果每乙個節點的大小固定(如4k,正如在sqlite中那樣),那麼可以進一步提高內部節點的度,降低樹的深度。

順序訪問指標的b+樹

對b+樹做了一點改變,每乙個葉子節點增加乙個指向相鄰葉子節點的指標,這樣子可以提高區間訪問的效能。

如圖,訪問key在15到30的data。

根據索引查詢資料時,分兩步

根據索引找到rowid(第一次b+樹查詢)

根據rowid查詢其他列的資料(第二次b+樹查詢)

通過兩次b+樹查詢避免了一次全表掃瞄。

1. 對某一行或某幾行新增primary key或unique約束,那麼資料庫會自動為這些列建立索引

2. 指定某一列為integer primary key,那麼這一列和rowid被指定為同一列。即可以通過rowid來獲取,也可以通過列名來獲取。

下面是乙個資料庫中乙個表的統計資訊,通過sqlite3_analyzer工具得到。

可以看到表中一共有3651條記錄,b樹的深度只有2,有33個葉子節點,1個非葉子節點。因此最多隻需要2次磁碟io就可以根據rowid找到一行的資料。

比如我們有這麼乙個表

查詢語句如下

select price from fruitsforsale where fruit=『peach』

由於沒有索引,因此不得不做一次全表掃瞄。通過順序訪問指標遍歷各個記錄(record),比較fruit這一列和『peatch』是否一致,如果一致,返回這一行的price列的值。

對『fruit』列加索引

如下,執行同樣的語句,可以根據索引找到目標列對應的rowid為4,然後根據rowid找到對應行,從而選出price。通過兩次b+樹查詢避免了全表查詢。這也是最簡單的情況 

多條索引命中

建立索引時,不要求索引是uique的,即索引表中的key可以是一樣的。

如下圖,索引表中有orange兩條記錄,找到第一條記錄時,根據順序訪問指標可以輕易找到下一條索引,避免另一次b+樹查詢。(rowid=1和rowid=23可能位於兩個不同的葉子節點中)

即這個查詢索引的過程,可以通過一次b+樹查和一次next操作完成,而next操作是很快的。

利用索引加快搜尋和排序

在大多情況下,我們需要同時進行查詢和排序操作,這時如果建立適當的索引,可以提高查詢效率。

比如下面表中對fruit和state兩列做了索引,執行下面的sql語句時,就不需要進行排序操作了,因為索引表是帶有順序的。

在sqlite中有乙個命令叫做explain query plan,可以檢視sqlite是如何執行查詢操作的。下面的資料庫語句不是引言中的查詢語句,原理一樣

注意detail列。不用索引時,使用的是「scan」這個詞,即全表掃瞄。使用索引時,使用的是「search」這個詞。

對於乙個41g的表來說,進行全表掃瞄的代價顯然是很大的。

**演算法和資料結構: 十 平衡查詢樹之b樹

mysql索引背後的資料結構及演算法原理

query planning(這篇是sqlite關於索引的文件)

explain query plan

mysql單錶百萬資料記錄分頁效能優化

sqlite 復合唯一索引 SQLite索引

索引 index 是一種特殊的查詢表,資料庫搜尋引擎用來加快資料檢索。簡單地說,索引是乙個指向表中資料的指標。乙個資料庫中的索引與一本書後邊的索引是非常相似的。例如,如果您想在一本討論某個話題的書中引用所有頁面,您首先需要指向索引,索引按字母順序列出了所有主題,然後指向乙個或多個特定的頁碼。索引有助...

sqlite 復合唯一索引 SQLite 索引

索引是一種特殊的查詢表,可以使用搜尋引擎的資料庫,以加快資料檢索。簡單地說,索引是乙個指標,表中的資料。乙個資料庫中的索引是非常相似在一本書的背部的索引。例如,如果你想在一本書中引用的所有頁面討論某個話題,先參考索引,按字母順序列出所有主題,再交由乙個或多個特定的頁碼。索引有助於加快select查詢...

sqlite 復合唯一索引 SQLite 索引

sqlite 索引 index 索引 index 是一種特殊的查詢表,資料庫搜尋引擎用來加快資料檢索。簡單地說,索引是乙個指向表中資料的指標。乙個資料庫中的索引與一本書的索引目錄是非常相似的。拿漢語字典的目錄頁 索引 打比方,我們可以按拼音 筆畫 偏旁部首等排序的目錄 索引 快速查詢到需要的字。索引...