普通索引和唯一索引的執行過程

2021-10-02 14:29:52 字數 2465 閱讀 4619

我們已經介紹過索引的結構和索引的幾種優化,我們再來看一下相同語句在不同索引型別的執行過程

這裡普通索引和唯一索引的情況有所不同

查詢過程

對於普通索引來說,查詢到滿足條件的第乙個記錄後,需要查詢下乙個記錄, 直到碰到第乙個不滿足條件的記錄。 對於唯一索引來說,由於索引定義了唯一性,查詢到第乙個滿足條件的記錄後,就會停止繼續檢索

這個不同帶來的效能差距會有多少呢? 基本上差不多

innodb 的資料是按資料頁為單位來讀寫的。也就是說,當需要讀一條記錄的時候,並不是將這個記錄本身從磁碟讀出來,而是以頁為單位,將其整體讀入記憶體。在 innodb 中,每個資料頁的大小預設是 16kb。 因為引擎是按頁讀寫的,所以說,當找到記錄的時候,它所在的資料頁就都在記憶體裡了。那麼,對於普通索引來說,要多做的那一次「查詢和判斷下一條記錄」的操作

更新過程

當需要更新乙個資料頁時,如果資料頁在記憶體中就直接更新,而如果這個資料頁還沒有在記憶體中的話,在不影響資料一致性的前提下,inoodb 會將這些更新操作快取在 change buffer 中,這樣就不需要從磁碟中讀入這個資料頁了。在下次查詢需要訪問這個資料頁的時候,將資料頁讀入記憶體,然後執行 change buffer 中與這個頁有關的操作。通過這種方式就能保證這個資料邏輯的正確性

雖然名字叫作 change buffer,實際上它是可以持久化的資料。也就是說,change buffer 在記憶體中有拷貝,也會被寫入到磁碟上

將 change buffer 中的操作應用到原資料頁,得到最新結果的過程稱為 merge。除了訪問這個資料頁會觸發 merge 外,系統有後台執行緒會定期 merge。在資料庫正常關閉 的過程中,也會執行 merge 操作

顯然,如果能夠將更新操作先記錄在 change buffer,減少讀磁碟,語句的執行速度會得到明顯的提公升。而且,資料讀入記憶體是需要占用 buffer pool 的,所以這種方式還能夠避免占用記憶體,提高記憶體利用率

什麼條件下可以使用 change buffer 呢?

對於唯一索引來說,所有的更新操作都要先判斷這個操作是否違反唯一性約束。比如,要 插入 ( id =1) 這個記錄,就要先判斷現在表中是否已經存在 1 的記錄,而這必須要將資料頁讀入記憶體才能判斷。如果都已經讀入到記憶體了,那直接更新記憶體會更快,就沒必要使 用 change buffer 了

因此,唯一索引的更新就不能使用 change buffer,只有普通索引可以使用

插入過程

如果要在這張表中插入乙個新記錄 (4) 的話,innodb 的處理流程是怎樣的

第一種情況是,這個記錄要更新的目標頁在記憶體中。 這時,innodb 的處理流程如下: 對於唯一索引來說,找到 3 和 5 之間的位置,判斷到沒有衝突,插入這個值,語句執行結束; 對於普通索引來說,找到 3 和 5 之間的位置,插入這個值,語句執行結束。

第二種情況是,這個記錄要更新的目標頁不在記憶體中。這時,innodb 的處理流程如下:

對於唯一索引來說,需要將資料頁讀入記憶體,判斷到沒有衝突,插入這個值,語句執行結束; 對於普通索引來說,則是將更新記錄在 change buffer,語句執行就結束了。

將資料從磁碟讀入記憶體涉及隨機 io 的訪問,是資料庫裡面成本最高的操作之一。change buffer 因為減少了隨機磁碟訪問,所以對更新效能的提公升是會很明顯的

change buffer 的使用場景

普通索引的所有場景,使用 change buffer 都可以起到加速作用嗎?

因為 merge 的時候是真正進行資料更新的時刻,而 change buffer 的主要目的就是將記錄的變更動作快取下來,所以在乙個資料頁做 merge 之前,change buffer 記錄的變更越多,收益就越大

對於寫多讀少的業務來說,頁面在寫完以後馬上被訪問到的概率比較小,此時 change buffer 的使用效果最好。這種業務模型常見的就是賬單類、日誌類的系統

假設乙個業務的更新模式是寫入之後馬上會做查詢,那麼即使滿足了條件,將更新先記錄在 change buffer,但之後由於馬上要訪問這個資料頁,會立即觸發 merge 過 程。這樣隨機訪問 io 的次數不會減少,反而增加了 change buffer 的維護代價

merge 的執行流程是這樣的:

從磁碟讀入資料頁到記憶體(老版本的資料頁);

從 change buffer 裡找出這個資料頁的 change buffer 記錄 (可能有多個),依次應 用,得到新版資料頁;

寫 redo log。這個 redo log 包含了資料的變更和 change buffer 的變更

change buffer 和 redo log

如果目標頁在記憶體 修改目標頁寫入 redo log 如果目標頁不在記憶體寫入change buffer redolog 記錄 change buffer 修改

redo log 主要節省的 是隨機寫磁碟的 io 消耗(轉成順序寫), 而 change buffer 主要節省的則是隨機讀磁碟 的 io 消耗。

普通索引和唯一索引的思考

這裡是修真院小課堂,本篇分析的主題是 普通索引和唯一索引的思考 索引是對資料庫表中一列或多列的值進行排序的一種結構,使用索引可快速訪問資料庫表中的特定資訊。從資料搜尋實現的角度來看,索引也是另外一類檔案 記錄,它包含著可以指示出相關資料記錄的各種記錄。在了解資料庫索引之前,首先了解一下資料庫索引的資...

MySQL 普通索引 唯一索引和主索引

1 普通索引 普通索引 由關鍵字key或index定義的索引 的唯一任務是加快對資料的訪問速度。因此,應該只為那些最經常出現在查詢條件 wherecolumn 或排序條件 orderbycolumn 中的資料列建立索引。只要有可能,就應該選擇乙個資料最整齊 最緊湊的資料列 如乙個整數型別的資料列 來...

MySQL 普通索引 唯一索引和主索引

1.普通索引 普通索引 由關鍵字key或index定義的索引 的唯一任務是加快對資料的訪問速度。因此,應該只為那些最經常出現在查詢條件 where column 或排序條件 order by column 中的資料列建立索引。只要有可能,就應該選擇乙個資料最整齊 最緊湊的資料列 如乙個整數型別的資料...