一:插入緩衝算法
二:二次寫數據庫
三:自適應哈希api
四:預讀緩存
1.插入緩衝(insert buffer)
插入緩衝(Insert Buffer/Change Buffer):提高插入性能,change buffering是insert buffer的增強,insert buffer只針對insert有效,change buffering對insert、delete、update(delete+insert)、purge都有效app
只對於非彙集索引(非惟一)的插入和更新有效,對於每一次的插入不是寫到索引頁中,而是先判斷插入的非彙集索引頁是否在緩衝池中,若是在則直接插入;若不在,則先放到Insert Buffer 中,再按照必定的頻率進行合併操做,再寫回disk。這樣一般能將多個插入合併到一個操做中,目的仍是爲了減小隨機IO帶來性能損耗。dom
使用插入緩衝的條件:
* 非彙集索引
* 非惟一索引異步
Change buffer是做爲buffer pool中的一部分存在。Innodb_change_buffering參數緩存所對應的操做:(update會被認爲是delete+insert)函數
innodb_change_buffering,設置的值有:inserts、deletes、purges、changes(inserts和deletes)、all(默認)、none。性能
all: 默認值,緩存insert, delete, purges操做
none: 不緩存
inserts: 緩存insert操做
deletes: 緩存delete操做
changes: 緩存insert和delete操做
purges: 緩存後臺執行的物理刪除操做spa
能夠經過參數控制其使用的大小:
innodb_change_buffer_max_size,默認是25%,即緩衝池的1/4。最大可設置爲50%。當MySQL實例中有大量的修改操做時,要考慮增大innodb_change_buffer_max_size
上面提過在必定頻率下進行合併,那所謂的頻率是什麼條件?
1)輔助索引頁被讀取到緩衝池中。正常的select先檢查Insert Buffer是否有該非彙集索引頁存在,如有則合併插入。
2)輔助索引頁沒有可用空間。空間小於1/32頁的大小,則會強制合併操做。
3)Master Thread 每秒和每10秒的合併操做。
2.二次寫(double write)
Doublewrite緩存是位於系統表空間的存儲區域,用來緩存InnoDB的數據頁從innodb buffer pool中flush以後並寫入到數據文件以前,因此當操做系統或者數據庫進程在數據頁寫磁盤的過程當中崩潰,Innodb能夠在doublewrite緩存中找到數據頁的備份而用來執行crash恢復。數據頁寫入到doublewrite緩存的動做所須要的IO消耗要小於寫入到數據文件的消耗,由於此寫入操做會以一次大的連續塊的方式寫入
在應用(apply)重作日誌前,用戶須要一個頁的副本,當寫入失效發生時,先經過頁的副原本還原該頁,再進行重作,這就是double write
doublewrite組成:
內存中的doublewrite buffer,大小2M。
物理磁盤上共享表空間中連續的128個頁,即2個區(extend),大小一樣爲2M。
對緩衝池的髒頁進行刷新時,不是直接寫磁盤,而是會經過memcpy()函數將髒頁先複製到內存中的doublewrite buffer,以後經過doublewrite 再分兩次,每次1M順序地寫入共享表空間的物理磁盤上,在這個過程當中,由於doublewrite頁是連續的,所以這個過程是順序寫的,開銷並非很大。在完成doublewrite頁的寫入後,再將doublewrite buffer 中的頁寫入各個 表空間文件中,此時的寫入則是離散的。若是操做系統在將頁寫入磁盤的過程當中發生了崩潰,在恢復過程當中,innodb能夠從共享表空間中的doublewrite中找到該頁的一個副本,將其複製到表空間文件,再應用重作日誌。
3.自適應哈希索引(ahi)
Adaptive Hash index屬性使得InnoDB更像是內存數據庫。該屬性經過innodb_adapitve_hash_index開啓,也能夠經過—skip-innodb_adaptive_hash_index參數
關閉
Innodb存儲引擎會監控對錶上二級索引的查找,若是發現某二級索引被頻繁訪問,二級索引成爲熱數據,創建哈希索引能夠帶來速度的提高
常常訪問的二級索引數據會自動被生成到hash索引裏面去(最近連續被訪問三次的數據),自適應哈希索引經過緩衝池的B+樹構造而來,所以創建的速度很快。
哈希(hash)是一種很是快的等值查找方法,在通常狀況下這種查找的時間複雜度爲O(1),即通常僅須要一次查找就能定位數據。而B+樹的查找次數,取決於B+樹的高度,在生產環境中,B+樹的高度通常3-4層,故須要3-4次的查詢。
innodb會監控對錶上個索引頁的查詢。若是觀察到創建哈希索引能夠帶來速度提高,則自動創建哈希索引,稱之爲自適應哈希索引(Adaptive Hash Index,AHI)。
AHI有一個要求,就是對這個頁的連續訪問模式必須是同樣的。
例如對於(a,b)訪問模式狀況:
where a = xxx
where a = xxx and b = xxx
特色
一、無序,沒有樹高
二、下降對二級索引樹的頻繁訪問資源,索引樹高<=4,訪問索引:訪問樹、根節點、葉子節點
三、自適應
三、缺陷
一、hash自適應索引會佔用innodb buffer pool;
二、自適應hash索引只適合搜索等值的查詢,如select * from table where index_col='xxx',而對於其餘查找類型,如範圍查找,是不能使用的;
三、極端狀況下,自適應hash索引纔有比較大的意義,能夠下降邏輯讀。
4.預讀(read ahead)
InnoDB使用兩種預讀算法來提升I/O性能:線性預讀(linear read-ahead)和隨機預讀(randomread-ahead)
爲了區分這兩種預讀的方式,咱們能夠把線性預讀放到以extent爲單位,而隨機預讀放到以extent中的page爲單位。線性預讀着眼於將下一個extent提早讀取到buffer pool中,而隨機預讀着眼於將當前extent中的剩餘的page提早讀取到buffer pool中。
線性預讀(linear read-ahead)
方式有一個很重要的變量控制是否將下一個extent預讀到buffer pool中,經過使用配置參數innodb_read_ahead_threshold,能夠控制Innodb執行預讀操做的時間。若是一個extent中的被順序讀取的page超過或者等於該參數變量時,Innodb將會異步的將下一個extent讀取到buffer pool中,innodb_read_ahead_threshold能夠設置爲0-64的任何值,默認值爲56,值越高,訪問模式檢查越嚴格
例如,若是將值設置爲48,則InnoDB只有在順序訪問當前extent中的48個pages時才觸發線性預讀請求,將下一個extent讀到內存中。若是值爲8,InnoDB觸發異步預讀,即便程序段中只有8頁被順序訪問。你能夠在MySQL配置文件中設置此參數的值,或者使用SET GLOBAL須要該SUPER權限的命令動態更改該參數。
在沒有該變量以前,當訪問到extent的最後一個page的時候,Innodb會決定是否將下一個extent放入到buffer pool中。
隨機預讀(randomread-ahead)
隨機預讀方式則是表示當同一個extent中的一些page在buffer pool中發現時,Innodb會將該extent中的剩餘page一併讀到buffer pool中,因爲隨機預讀方式給Innodb code帶來了一些沒必要要的複雜性,同時在性能也存在不穩定性,在5.5中已經將這種預讀方式廢棄。要啓用此功能,請將配置變量設置innodb_random_read_ahead爲ON。