天天看點

索引(二)

查詢過程

1,查詢語句在索引樹上查找過程,先通過B+樹從樹根開始按層搜尋到葉子節點,資料頁内部通過二分法定位記錄。

1)對于普通索引,查找到滿足條件的第一個記錄後,需要查找下一個記錄,直到第一個不滿足條件的記錄。

2)對于唯一索引,由于索引定義了唯一性,查詢到第一個滿足條件的記錄後,就會停止搜尋。

2,兩種不同方式帶來的性能差距比較小,InnoDB資料是按資料頁為機關來讀寫的,當需要讀一條記錄時,不是将這條記錄從磁盤讀出,而是将這條記錄的資料頁整體讀入記憶體。

1)InnoDB中,每個資料頁的大小預設是16KB。

2)普通索引查找和判斷下一條記錄,隻需要一次指針尋找和一次計算,但查找的記錄剛好是資料頁的最後一條記錄,則取下一條記錄時必須讀取下一個資料頁,操作稍微複雜一些。

3)對于整型字段,一個資料頁可以存放近千個key,讀取下一個資料頁的機率比較低,是以在計算平均性能差異時忽略不計。

更新過程

1,更新語句,如果資料頁在記憶體中直接更新,資料頁不在記憶體中,在不影響資料一緻性的前提下,InnoDB将更新緩存在change buffer中。

1)不從磁盤讀入資料頁,在下次查詢需要通路資料頁時再将資料頁讀入記憶體,然後執行change buffer中與資料頁有關的操作,保證資料邏輯的正确性。

2)change buffer中的操作應用到原資料頁的過程為merge,通路資料頁會觸發merge,系統背景線程也會定期merge,資料庫正常關閉也會執行merge操作。

2,change buffer是可以持久化的資料,在記憶體中有拷貝,也會寫入到磁盤。

1)資料讀入記憶體需要占用buffer pool,使用change buffer可減少讀磁盤,提升語句執行速度,還可避免占用記憶體,提高記憶體使用率。

2)change buffer占用的buffer pool的記憶體,大小可通過參數innodb_change_buffer_max_size動态設定,設定為50時,表示最多隻能占buffer pool的50%。

change buffer

1,唯一索引不使用change buffer,普通索引使用。

1)唯一索引,所有的更新都要先判斷索引的唯一性,例如插入資料時需要先判斷表中key是否存在,則必須将資料頁讀入記憶體,沒有沖突則插入資料,語句執行結束,也就沒必要使用change buffer了。

2)普通索引可以使用change buffer,将更新記錄在change buffer中,語句執行結束。

2,将資料從磁盤讀入記憶體涉及随機IO的通路,是資料庫中成本最高的操作之一,change buffer減少了随機磁盤的通路,對更新的性能提升比較明顯。

3,merge才是真正資料更新過程,資料頁merge之前,change buffer記錄的變更越多,性能提升越明顯。

1)在帳單類、日志類寫多讀少的業務中,頁面寫完立即通路的機率較小,change buffer使用效果佳。

2)業務更新之後立刻查詢,更新記錄在change buffer裡,但立刻通路這個資料頁觸發merge過程,随機通路IO次數并不會減少,反而增加了change buffer的維護代價,可以關閉change buffer。

3)普通索引和唯一索引盡量選擇普通索引,配合使用change buffer,更新優化明顯。

change buffer和redo log

1,執行一條更新語句:

1)如果資料頁在記憶體中,直接更新記憶體同時記錄到redo log,之後執行查詢操作直接從記憶體傳回;

2)如果資料頁不在記憶體中,将更新記錄到記憶體change buffer區域,并記錄到redo log中,之後執行查詢操作,需要從磁盤讀入資料頁到記憶體,再應用change buffer操作,最後傳回正确結果。

2,一條更新語句插入多個記錄,按以上原則寫到記憶體或change buffer中,寫了兩處記憶體,多條記錄順序寫入redo log,寫一次磁盤。

3,redo log主要節省随機寫磁盤的IO消耗(轉成順序寫),change buffer主要節省随機讀磁盤的IO消耗。

繼續閱讀