MySQL具体解释(21)------------缓存參数优化
數(shù)據(jù)庫屬于 IO 密集型的應(yīng)用程序。其主要職責(zé)就是數(shù)據(jù)的管理及存儲(chǔ)工作。
而我們知道,從內(nèi)存中讀取一個(gè)數(shù)據(jù)庫的時(shí)間是微秒級(jí)別,而從一塊普通硬盤上讀取一個(gè)IO是在毫秒級(jí)別,二者相差3個(gè)數(shù)量級(jí)。所以,要優(yōu)化數(shù)據(jù)庫。首先第一步須要優(yōu)化的就是 IO,盡可能將磁盤IO轉(zhuǎn)化為內(nèi)存IO。本文先從 MySQL 數(shù)據(jù)庫IO相關(guān)參數(shù)(緩存參數(shù))的角度來看看能夠通過哪些參數(shù)進(jìn)行IO優(yōu)化:
query_cache_size/query_cache_type (global)
Query cache 作用于整個(gè) MySQL Instance,主要用來緩存 MySQL 中的 ResultSet。也就是一條SQL語句運(yùn)行的結(jié)果集,所以只只能針對(duì)select語句。
當(dāng)我們打開了 Query Cache 功能。MySQL在接受到一條select語句的請(qǐng)求后。假設(shè)該語句滿足Query Cache的要求(未顯式說明不同意使用Query Cache。或者已經(jīng)顯式申明須要使用Query Cache),MySQL 會(huì)直接依據(jù)預(yù)先設(shè)定好的HASH算法將接受到的select語句以字符串方式進(jìn)行hash,然后到Query Cache 中直接查找是否已經(jīng)緩存。
也就是說。假設(shè)已經(jīng)在緩存中。該select請(qǐng)求就會(huì)直接將數(shù)據(jù)返回,從而省略了后面全部的步驟(如 SQL語句的解析,優(yōu)化器優(yōu)化以及向存儲(chǔ)引擎請(qǐng)求數(shù)據(jù)等),極大的提高性能。
當(dāng)然,Query Cache 也有一個(gè)致命的缺陷,那就是當(dāng)某個(gè)表的數(shù)據(jù)有不論什么不論什么變化,都會(huì)導(dǎo)致全部引用了該表的select語句在Query Cache 中的緩存數(shù)據(jù)失效。
所以,當(dāng)我們的數(shù)據(jù)變化很頻繁的情況下,使用Query Cache 可能會(huì)得不償失。
Query Cache的使用須要多個(gè)參數(shù)配合。當(dāng)中最為關(guān)鍵的是 query_cache_size 和 query_cache_type 。前者設(shè)置用于緩存 ResultSet 的內(nèi)存大小,后者設(shè)置在何場(chǎng)景下使用 Query Cache。
在以往的經(jīng)驗(yàn)來看,假設(shè)不是用來緩存基本不變的數(shù)據(jù)的MySQL數(shù)據(jù)庫,query_cache_size 一般 256MB 是一個(gè)比較合適的大小。
當(dāng)然。這能夠通過計(jì)算Query Cache的命中率(Qcache_hits/(Qcache_hits+Qcache_inserts)*100))來進(jìn)行調(diào)整。query_cache_type能夠設(shè)置為0(OFF),1(ON)或者2(DEMOND),分別表示全然不使用query cache,除顯式要求不使用query cache(使用sql_no_cache)之外的全部的select都使用query cache,僅僅有顯示要求才使用query cache(使用sql_cache)。
binlog_cache_size (global)
Binlog Cache 用于在打開了二進(jìn)制日志(binlog)記錄功能的環(huán)境。是 MySQL 用來提高binlog的記錄效率而設(shè)計(jì)的一個(gè)用于短時(shí)間內(nèi)暫時(shí)緩存binlog數(shù)據(jù)的內(nèi)存區(qū)域。
一般來說,假設(shè)我們的數(shù)據(jù)庫中沒有什么大事務(wù),寫入也不是特別頻繁,2MB~4MB是一個(gè)合適的選擇。
可是假設(shè)我們的數(shù)據(jù)庫大事務(wù)較多,寫入量比較大,可與適當(dāng)調(diào)高binlog_cache_size。同一時(shí)候,我們能夠通過binlog_cache_use 以及 binlog_cache_disk_use來分析設(shè)置的binlog_cache_size是否足夠,是否有大量的binlog_cache因?yàn)閮?nèi)存大小不夠而使用暫時(shí)文件(binlog_cache_disk_use)來緩存了。
key_buffer_size (global)
Key Buffer 可能是大家最為熟悉的一個(gè) MySQL 緩存參數(shù)了,尤其是在 MySQL 沒有更換默認(rèn)存儲(chǔ)引擎的時(shí)候。非常多朋友可能會(huì)發(fā)現(xiàn),默認(rèn)的 MySQL 配置文件里設(shè)置最大的一個(gè)內(nèi)存參數(shù)就是這個(gè)參數(shù)了。key_buffer_size 參數(shù)用來設(shè)置用于緩存 MyISAM存儲(chǔ)引擎中索引文件的內(nèi)存區(qū)域大小。假設(shè)我們有足夠的內(nèi)存,這個(gè)緩存區(qū)域最好是可以存放下我們?nèi)康?MyISAM 引擎表的全部索引。以盡可能提高性能。
此外,當(dāng)我們?cè)谑褂肕yISAM 存儲(chǔ)的時(shí)候有一個(gè)及其重要的點(diǎn)須要注意。因?yàn)?MyISAM 引擎的特性限制了他只只會(huì)緩存索引塊到內(nèi)存中。而不會(huì)緩存表數(shù)據(jù)庫塊。
所以,我們的 SQL 一定要盡可能讓過濾條件都在索引中。以便讓緩存幫助我們提高查詢效率。
bulk_insert_buffer_size (thread)
和key_buffer_size一樣,這個(gè)參數(shù)相同也僅作用于使用 MyISAM存儲(chǔ)引擎,用來緩存批量插入數(shù)據(jù)的時(shí)候暫時(shí)緩存寫入數(shù)據(jù)。當(dāng)我們使用例如以下幾種數(shù)據(jù)寫入語句的時(shí)候,會(huì)使用這個(gè)內(nèi)存區(qū)域來緩存批量結(jié)構(gòu)的數(shù)據(jù)以幫助批量寫入數(shù)據(jù)文件:
insert … select …
insert … values (…) ,(…),(…)…
load data infile… into… (非空表)
innodb_buffer_pool_size(global)
當(dāng)我們使用InnoDB存儲(chǔ)引擎的時(shí)候,innodb_buffer_pool_size 參數(shù)可能是影響我們性能的最為關(guān)鍵的一個(gè)參數(shù)了,他用來設(shè)置用于緩存 InnoDB 索引及數(shù)據(jù)塊的內(nèi)存區(qū)域大小。類似于 MyISAM 存儲(chǔ)引擎的 key_buffer_size 參數(shù),當(dāng)然,可能更像是 Oracle 的 db_cache_size。簡(jiǎn)單來說,當(dāng)我們操作一個(gè) InnoDB 表的時(shí)候。返回的全部數(shù)據(jù)或者去數(shù)據(jù)過程中用到的不論什么一個(gè)索引塊,都會(huì)在這個(gè)內(nèi)存區(qū)域中走一遭。
和key_buffer_size 對(duì)于 MyISAM 引擎一樣,innodb_buffer_pool_size 設(shè)置了 InnoDB 存儲(chǔ)引擎需求最大的一塊內(nèi)存區(qū)域的大小,直接關(guān)系到 InnoDB存儲(chǔ)引擎的性能,所以假設(shè)我們有足夠的內(nèi)存。盡可將該參數(shù)設(shè)置到足夠打,將盡可能多的 InnoDB 的索引及數(shù)據(jù)都放入到該緩存區(qū)域中,直至所有。
我們能夠通過 (Innodb_buffer_pool_read_requests – Innodb_buffer_pool_reads) / Innodb_buffer_pool_read_requests * 100% 計(jì)算緩存命中率。并依據(jù)命中率來調(diào)整 innodb_buffer_pool_size 參數(shù)大小進(jìn)行優(yōu)化。
innodb_additional_mem_pool_size(global)
這個(gè)參數(shù)我們平時(shí)調(diào)整的可能不是太多,非常多人都使用了默認(rèn)值,可能非常多人都不是太熟悉這個(gè)參數(shù)的作用。innodb_additional_mem_pool_size 設(shè)置了InnoDB存儲(chǔ)引擎用來存放數(shù)據(jù)字典信息以及一些內(nèi)部數(shù)據(jù)結(jié)構(gòu)的內(nèi)存空間大小,所以當(dāng)我們一個(gè)MySQL Instance中的數(shù)據(jù)庫對(duì)象非常多的時(shí)候,是須要適當(dāng)調(diào)整該參數(shù)的大小以確保全部數(shù)據(jù)都能存放在內(nèi)存中提高訪問效率的。
這個(gè)參數(shù)大小是否足夠還是比較easy知道的,由于當(dāng)過小的時(shí)候,MySQL 會(huì)記錄 Warning 信息到數(shù)據(jù)庫的 error log 中,這時(shí)候你就知道該調(diào)整這個(gè)參數(shù)大小了。
innodb_log_buffer_size (global)
這是 InnoDB 存儲(chǔ)引擎的事務(wù)日志所使用的緩沖區(qū)。類似于 Binlog Buffer,InnoDB 在寫事務(wù)日志的時(shí)候。為了提高性能。也是先將信息寫入 Innofb Log Buffer 中,當(dāng)滿足 innodb_flush_log_trx_commit 參數(shù)所設(shè)置的對(duì)應(yīng)條件(或者日志緩沖區(qū)寫滿)之后,才會(huì)將日志寫到文件(或者同步到磁盤)中。
能夠通過 innodb_log_buffer_size 參數(shù)設(shè)置其能夠使用的最大內(nèi)存空間。
注:innodb_flush_log_trx_commit 參數(shù)對(duì) InnoDB Log 的寫入性能有很關(guān)鍵的影響。
該參數(shù)能夠設(shè)置為0,1,2,解釋例如以下:
0:log buffer中的數(shù)據(jù)將以每秒一次的頻率寫入到log file中。且同一時(shí)候會(huì)進(jìn)行文件系統(tǒng)到磁盤的同步操作,可是每一個(gè)事務(wù)的commit并不會(huì)觸發(fā)不論什么log buffer 到log file的刷新或者文件系統(tǒng)到磁盤的刷新操作。
1:在每次事務(wù)提交的時(shí)候?qū)og buffer 中的數(shù)據(jù)都會(huì)寫入到log file。同一時(shí)候也會(huì)觸發(fā)文件系統(tǒng)到磁盤的同步;
2:事務(wù)提交會(huì)觸發(fā)log buffer 到log file的刷新,但并不會(huì)觸發(fā)磁盤文件系統(tǒng)到磁盤的同步。此外。每秒會(huì)有一次文件系統(tǒng)到磁盤同步操作。
此外,MySQL文檔中還提到。這幾種設(shè)置中的每秒同步一次的機(jī)制,可能并不會(huì)全然確保很準(zhǔn)確的每秒就一定會(huì)發(fā)生同步,還取決于進(jìn)程調(diào)度的問題。實(shí)際上。InnoDB 是否能真正滿足此參數(shù)所設(shè)置值代表的意義正常 Recovery 還是受到了不同 OS 下文件系統(tǒng)以及磁盤本身的限制。可能有些時(shí)候在并沒有真正完畢磁盤同步的情況下也會(huì)告訴 mysqld 已經(jīng)完畢了磁盤同步。
innodb_max_dirty_pages_pct (global)
這個(gè)參數(shù)和上面的各個(gè)參數(shù)不同,他不是用來設(shè)置用于緩存某種數(shù)據(jù)的內(nèi)存大小的一個(gè)參數(shù)。而是用來控制在 InnoDB Buffer Pool 中可以不用寫入數(shù)據(jù)文件里的Dirty Page 的比例(已經(jīng)被修但還沒有從內(nèi)存中寫入到數(shù)據(jù)文件的臟數(shù)據(jù))。這個(gè)比例值越大,從內(nèi)存到磁盤的寫入操作就會(huì)相對(duì)降低。所以可以一定程度下降低寫入操作的磁盤IO。
可是,假設(shè)這個(gè)比例值過大,當(dāng)數(shù)據(jù)庫 Crash 之后重新啟動(dòng)的時(shí)間可能就會(huì)非常長。由于會(huì)有大量的事務(wù)數(shù)據(jù)須要從日志文件恢復(fù)出來寫入數(shù)據(jù)文件里。同一時(shí)候,過大的比例值同一時(shí)候可能也會(huì)造成在達(dá)到比例設(shè)定上限后的 flush 操作“過猛”而導(dǎo)致性能波動(dòng)非常大。
上面這幾個(gè)參數(shù)是 MySQL 中為了降低磁盤物理IO而設(shè)計(jì)的主要參數(shù)。對(duì) MySQL 的性能起到了至關(guān)關(guān)鍵的數(shù)據(jù)。 —EOF— 依照?mcsrainbow?朋友的要求。這里列一下依據(jù)以往經(jīng)驗(yàn)得到的相關(guān)參數(shù)的建議值:- query_cache_type : 假設(shè)全部使用innodb存儲(chǔ)引擎,建議為0,假設(shè)使用MyISAM 存儲(chǔ)引擎,建議為2。同一時(shí)候在SQL語句中顯式控制是否是喲你gquery cache
- query_cache_size: 依據(jù) 命中率(Qcache_hits/(Qcache_hits+Qcache_inserts)*100))進(jìn)行調(diào)整,一般不建議太大。256MB可能已經(jīng)差點(diǎn)兒相同了。大型的配置型靜態(tài)數(shù)據(jù)可適當(dāng)調(diào)大
- binlog_cache_size: 一般環(huán)境2MB~4MB是一個(gè)合適的選擇。事務(wù)較大且寫入頻繁的數(shù)據(jù)庫環(huán)境能夠適當(dāng)調(diào)大,但不建議超過32MB
- key_buffer_size: 假設(shè)不使用MyISAM存儲(chǔ)引擎,16MB足以,用來緩存一些系統(tǒng)表信息等。假設(shè)使用 MyISAM存儲(chǔ)引擎。在內(nèi)存同意的情況下,盡可能將全部索引放入內(nèi)存,簡(jiǎn)單來說就是“越大越好”
- bulk_insert_buffer_size: 假設(shè)常常性的須要使用批量插入的特殊語句(上面有說明)來插入數(shù)據(jù),能夠適當(dāng)調(diào)大該參數(shù)至16MB~32MB,不建議繼續(xù)增大,某人8MB
- innodb_buffer_pool_size: 假設(shè)不使用InnoDB存儲(chǔ)引擎,能夠不用調(diào)整這個(gè)參數(shù)。假設(shè)須要使用,在內(nèi)存同意的情況下,盡可能將全部的InnoDB數(shù)據(jù)文件存放如內(nèi)存中,相同將但來說也是“越大越好”
- innodb_additional_mem_pool_size: 一般的數(shù)據(jù)庫建議調(diào)整到8MB~16MB。假設(shè)表特別多。能夠調(diào)整到32MB。能夠依據(jù)error log中的信息推斷是否須要增大
- innodb_log_buffer_size: 默認(rèn)是1MB,系的如頻繁的系統(tǒng)可適當(dāng)增大至4MB~8MB。當(dāng)然如上面介紹所說。這個(gè)參數(shù)實(shí)際上還和另外的flush參數(shù)相關(guān)。一般來說不建議超過32MB
- innodb_max_dirty_pages_pct: 依據(jù)以往的經(jīng)驗(yàn),重新啟動(dòng)恢復(fù)的數(shù)據(jù)假設(shè)要超過1GB的話,啟動(dòng)速度會(huì)比較慢,差點(diǎn)兒難以接受,所以建議不大于 1GB/innodb_buffer_pool_size(GB)*100 這個(gè)值。當(dāng)然,假設(shè)你能夠忍受啟動(dòng)時(shí)間比較長,并且希望盡量降低內(nèi)存至磁盤的flush,能夠?qū)⑦@個(gè)值調(diào)整到90,但不建議超過90
注:以上取值范圍只不過我的依據(jù)以往遇到的數(shù)據(jù)庫場(chǎng)景所得到的一些優(yōu)化經(jīng)驗(yàn)值,并不一定適用于全部場(chǎng)景,所以在實(shí)際優(yōu)化過程中還須要大家自己不斷的調(diào)整分析。也歡迎大家隨時(shí)通過 Mail 與我聯(lián)系溝通交流優(yōu)化或者是架構(gòu)方面的技術(shù),一起探討相互學(xué)習(xí)。
轉(zhuǎn)載于:https://www.cnblogs.com/yutingliuyl/p/6834888.html
總結(jié)
以上是生活随笔為你收集整理的MySQL具体解释(21)------------缓存參数优化的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux文件系统上的特殊权限
- 下一篇: Activiti+Oracle,在数据量