Mysql數(shù)據(jù)庫(kù)性能影響因素

影響MYSQL性能因素

1.服務(wù)器硬件

2.操作系統(tǒng)

3.數(shù)據(jù)庫(kù)引擎

4.數(shù)據(jù)庫(kù)配置參數(shù)

5.表結(jié)構(gòu)的設(shè)計(jì)和SQL語(yǔ)句的優(yōu)化



服務(wù)器硬件

cpu

多個(gè)cpu,對(duì)處理數(shù)據(jù)庫(kù)并發(fā)有幫助,一個(gè)SQL語(yǔ)句是在一個(gè)cpu執(zhí)行的,多個(gè)cpu,可同時(shí)處理多個(gè)并發(fā)的SQL語(yǔ)句??蛇x擇64位,16或者 32核的cpu。

64位cpu需要安裝64位系統(tǒng)


cpu核數(shù)和cpu線程數(shù)理解:

CPU個(gè)數(shù)即CPU芯片個(gè)數(shù)

CPU的核心數(shù)是指物理上,也就是硬件上存在著幾個(gè)核心。比如,雙核就是包括2個(gè)相對(duì)獨(dú)立的CPU核心單元組,四核就包含4個(gè)相對(duì)獨(dú)立的CPU核心單元組。

線程數(shù)是一種邏輯的概念,簡(jiǎn)單地說(shuō),就是模擬出的CPU核心數(shù)。比如,可以通過(guò)一個(gè)CPU核心數(shù)模擬出2線程的CPU,也就是說(shuō),這個(gè)單核心的CPU被模擬成了一個(gè)類似雙核心CPU的功能。我們從任務(wù)管理器的性能標(biāo)簽頁(yè)中看到的是兩個(gè)CPU。?比如Inte l賽揚(yáng)G460是單核心,雙線程的CPU,Intel 酷睿i3 3220是雙核心 四線程,Intel 酷睿i7 4770K是四核心 八線程 ,Intel 酷睿i5 4570是四核心 四線程等等。?對(duì)于一個(gè)CPU,線程數(shù)總是大于或等于核心數(shù)的。一個(gè)核心最少對(duì)應(yīng)一個(gè)線程,但通過(guò)超線程技術(shù),一個(gè)核心可以對(duì)應(yīng)兩個(gè)線程,也就是說(shuō)它可以同時(shí)運(yùn)行兩個(gè)線程。

內(nèi)存

內(nèi)存大小大于數(shù)據(jù)庫(kù)數(shù)據(jù)的時(shí)候,再大的內(nèi)存就沒(méi)啥意義了。內(nèi)存可以把數(shù)據(jù)庫(kù)數(shù)據(jù)緩存,加快讀。對(duì)于寫,每次寫先緩存在內(nèi)存,等寫的內(nèi)容多了,一次性寫入磁盤,減少磁盤IO

磁盤

容量? 傳輸速度? 訪問(wèn)時(shí)間? 主軸速度? 物理尺寸

Raid卡

raid0,同時(shí)往多塊磁盤讀寫,速度快,但是沒(méi)冗余

raid1,有一半磁盤做冗余

raid5,只可以壞一個(gè)磁盤。因?yàn)橛昧似媾夹r?yàn),所以寫入的時(shí)候,需要寫入檢驗(yàn)數(shù)據(jù),所以寫入的時(shí)候慢。但是讀取的時(shí)候快,因?yàn)椴挥脤懭胄r?yàn)數(shù)據(jù)。但是壞了一塊磁盤,需要調(diào)用其他所有磁盤的數(shù)據(jù),進(jìn)行恢復(fù)這塊磁盤數(shù)據(jù),會(huì)導(dǎo)致讀寫慢??梢杂迷趶膸?kù)。

raid10,先raid1,然后再把raid1組合成raid0

raid

raid0 和 raid5適合用于slave數(shù)據(jù)庫(kù)(因?yàn)閞aid0沒(méi)冗余? raid5壞了一塊磁盤后,要通過(guò)其他幾個(gè)磁盤一起恢復(fù),會(huì)導(dǎo)致當(dāng)時(shí)的磁盤io很慢)

raid1和raid10可以用于主或者從數(shù)據(jù)庫(kù)

SSD磁盤

SSD磁盤有更好的隨機(jī)讀寫和支持更大的并發(fā)IO大。

PCIE-SSD性能比ssd好,但是昂貴。PCIE-SSD會(huì)占用內(nèi)存,不建議使用raid,因?yàn)槌杀颈緛?lái)就昂貴了

SSD磁盤用在隨機(jī)IO比較多的場(chǎng)景,比如內(nèi)存只有20G,但是數(shù)據(jù)庫(kù)數(shù)據(jù)又100G.那么數(shù)據(jù)不可能全部緩存到內(nèi)存,所以很多數(shù)據(jù)需要從磁盤讀取,此時(shí)可以使用固態(tài);可以使用在單線程負(fù)載IO場(chǎng)景,比如slave種的IO線程就是單線程的,可以使用SSD加快這個(gè)線程接收master的dump線程推送過(guò)來(lái)的信息。

網(wǎng)絡(luò)

網(wǎng)絡(luò)帶寬如果太小,影響并發(fā)

網(wǎng)絡(luò)延時(shí),影響連接和發(fā)送數(shù)據(jù)



操作系統(tǒng)

Linux



數(shù)據(jù)庫(kù)引擎

innodb



數(shù)據(jù)庫(kù)相關(guān)配置


文件系統(tǒng)配置

linux系統(tǒng)下最好使用xfs文件系統(tǒng)

ext4 或者ext3文件系統(tǒng),需要再/etc/fastab設(shè)置:

/dev/sda3? /? ext4? noatime,nodiratime,data=writeback 1 1

noatime,nodiratime 分別是對(duì)訪問(wèn)文件和訪問(wèn)文件夾的時(shí)間戳不要記錄,減少IO操作

writeback 表示文件系統(tǒng)把數(shù)據(jù)寫入磁盤,不需要記錄日志,直接把原數(shù)據(jù)刷入磁盤就行,因?yàn)閿?shù)據(jù)innodb自己有redo日志。(這里是三個(gè)值的?writeback?? ordered【記錄部分日志】 journal【記錄全部日志】)

操作系統(tǒng)參數(shù)配置

net.core.somaxconn? #是Linux中的一個(gè)kernel參數(shù),表示socket監(jiān)聽(tīng)(listen)的backlog上限。什么是backlog呢?backlog就是socket的監(jiān)聽(tīng)隊(duì)列,當(dāng)一個(gè)請(qǐng)求(request)尚未被處理或建立時(shí),他會(huì)進(jìn)入backlog。而socket server可以一次性處理backlog中的所有請(qǐng)求,處理后的請(qǐng)求不再位于監(jiān)聽(tīng)隊(duì)列中。當(dāng)server處理請(qǐng)求較慢,以至于監(jiān)聽(tīng)隊(duì)列被填滿后,新來(lái)的請(qǐng)求會(huì)被拒絕。

mysql配置讀取

mysql --help --version|grep -A 1 'Default options'? #通過(guò)這一句命令查看操作系統(tǒng)mysql讀取配置文件的位置的先后

centos配置讀取順序:

/etc/my.cnf /etc/mysql/my.cnf /usr/local/mysql/etc/my.cnf ~/.my.cnf

配置里有全局配置和session配置

set global xxxx=xxxxx;? #全局配置,只對(duì)還沒(méi)登陸的session有效,對(duì)于已經(jīng)登陸的session,需要先退出,再登陸進(jìn)來(lái)才生效。

set xxxx=xxxxxx;? #session配置

INODB內(nèi)存分配

innodb_buffer_pool_size? #一般為總內(nèi)存的75%以上,緩存索引和數(shù)據(jù)

key_buffer_szie? #myisam存儲(chǔ)引擎的內(nèi)存緩存大小,只緩存索引

#下面的四個(gè)參數(shù)為每一個(gè)線程設(shè)置,一個(gè)線程就分配指定的內(nèi)存。如果線程數(shù)量過(guò)多,那么總分配的內(nèi)存也會(huì)很多,所以要小心配置

sort_buffer_size? #排序緩存大小

join_buffer_size? #連接緩沖區(qū)的大小,如果一個(gè)查詢中,關(guān)聯(lián)多張表,會(huì)對(duì)每個(gè)關(guān)聯(lián)分配一個(gè)連接緩沖,所以每個(gè)查詢會(huì)有多個(gè)緩沖。

read_buffer_szie?? #當(dāng)myisam表進(jìn)行全表掃描,分配讀緩沖池大小,當(dāng)mysql讀需要才會(huì)分配。

read_rnd_buffer_size #sout_buffer_size排序的是key_values,而不是數(shù)據(jù)。排序好key后,就去磁盤找數(shù)據(jù),然后把數(shù)據(jù)保存再read_rnd_buffer_size,找數(shù)據(jù)這個(gè)過(guò)程是隨機(jī)讀的。當(dāng)數(shù)據(jù)放到read_rnd_buffer_size后,再通過(guò)key去read_rnd_buffer_size讀數(shù)據(jù)就是順序讀了。


INODB IO相關(guān)配置

提交數(shù)據(jù)得時(shí)候,先寫入buffer_poo緩存,而不是直接刷入磁盤的。因?yàn)槊看翁峤粩?shù)據(jù),都刷入磁盤,那么很消耗IO。而且每次寫入磁盤,可能不一定是順序?qū)懭氲?。在每次提交的時(shí)候,都會(huì)寫入日志到redo文件。redo文件的磁盤刷入,是順序的。

innodb_log_file_size? #每一個(gè)redo日志文件的大小。根據(jù)業(yè)務(wù)大小,業(yè)務(wù)比較大的,設(shè)置大點(diǎn)。

innodb_log_files_in_group? #有多少個(gè)日志組,一般一個(gè)日志組就行了

innodb_log_buffer_size? #控制redo日志緩沖區(qū)大小,不再buffer_pool里面。不需要太大(32M-128M),因?yàn)槊?s或者每次事務(wù)提交,都會(huì)自動(dòng)把緩存刷入磁盤的。

innodb_flush_log_at_trx_commit

#####值可以為以下選項(xiàng)

1)如果innodb_flush_log_at_trx_commit設(shè)置為0,log buffer將每秒一次都把log buffer刷到文件系統(tǒng)中去,并且調(diào)用文件系統(tǒng)的“flush”操作將緩存刷新到磁盤上去,在事務(wù)提交的時(shí)候,不會(huì)主動(dòng)觸發(fā)寫入磁盤的操作。log buffer寫到文件系統(tǒng)中,一般只是從log buffer的內(nèi)存轉(zhuǎn)移的文件系統(tǒng)的內(nèi)存緩存中,對(duì)底層IO沒(méi)有壓力

2) 如果innodb_flush_log_at_trx_commit設(shè)置為1,每次事務(wù)提交時(shí)MySQL都把log buffer刷到文件系統(tǒng)中去,并且調(diào)用文件系統(tǒng)的“flush”操作將緩存刷新到磁盤上去.

3)如果innodb_flush_log_at_trx_commit設(shè)置為2,每次事務(wù)提交時(shí)MySQL會(huì)把log buffer刷到文件系統(tǒng)中去,但是每隔一秒調(diào)用文件系統(tǒng)的“flush”操作將緩存刷新到磁盤上去。該模式下,MySQL會(huì)每秒執(zhí)行一次flush(刷到磁盤)操作。(為2性能最好)


redo的buffer刷新圖

sync_binlog?

值為0,像操作系統(tǒng)刷其他文件的機(jī)制一樣,MySQL不會(huì)同步到磁盤中去而是依賴操作系統(tǒng)來(lái)刷新binary log。

當(dāng)sync_binlog =N (N>0) ,MySQL 在每寫 N次 二進(jìn)制日志binary log時(shí),會(huì)使用fdatasync()函數(shù)將它的寫二進(jìn)制日志binary log同步到磁盤中去。生產(chǎn)環(huán)境用了sync_binlog=1

innodb_flush_method

默認(rèn)是fdatasync,調(diào)用fsync()去刷數(shù)據(jù)文件與redo log的buffer

為O_DSYNC時(shí),innodb會(huì)使用O_SYNC方式打開(kāi)和刷寫redo log(直接不經(jīng)過(guò)os緩存,寫入磁盤),使用fsync()刷寫數(shù)據(jù)文件(使用os緩存再刷新到磁盤)

為O_DIRECT時(shí),innodb使用O_DIRECT打開(kāi)數(shù)據(jù)文件(數(shù)據(jù)不經(jīng)過(guò)os緩存,直接刷入磁盤),redo日志還是需要經(jīng)過(guò)os緩存才可以刷入磁盤(生產(chǎn)環(huán)境使用)

一張圖就知道原理了

innodb_file_per_table=1?? #讓每個(gè)表都有自己的獨(dú)立空間,如果不設(shè)置為1,所有表都公用共享表空間了

innodb_doublewrite=1? #在寫入數(shù)據(jù)的時(shí)候,比如默認(rèn)的一個(gè)葉是16k,當(dāng)只寫入了6k,然后數(shù)據(jù)庫(kù)崩潰了,那么當(dāng)重啟做數(shù)據(jù)一致性恢復(fù)的時(shí)候,是恢復(fù)補(bǔ)回來(lái)的了。只有當(dāng)設(shè)置為1了,才可以恢復(fù)回來(lái)。

安全相關(guān)配置參數(shù)

expire_logs_days? #指定自動(dòng)清理binlog的天數(shù)

max_allowed_packet? #控制MYSQL可以接收的包的大小,默認(rèn)為1M,如果大于1M的插入和更新,就會(huì)出問(wèn)題

skip_name_resolve? 禁止DNS查找

sysdate_is_now?? #確保sysdate()返回確定性日期

read_only?????? #禁止非super權(quán)限的用戶寫入,一般用在slave服務(wù)器

skip_slave_start? #禁止slave自動(dòng)啟動(dòng),需要手動(dòng)start slave;

sql_mode? #定義SQL模式

???????????????? #STRICT_TRANS_TABLES為嚴(yán)格模式,就是插入無(wú)關(guān)內(nèi)容,直接返回error,不給插入。

??????????????? #NO_ENGINE_SUBSTITUTION 如果需要的存儲(chǔ)引擎被禁用或未編譯,那么拋出錯(cuò)誤。不設(shè)置此值時(shí),用默認(rèn)的存儲(chǔ)引擎替代,并拋出一個(gè)異常

其他常用配置

tmp_table_size? max_head_table_size? #這兩個(gè)參數(shù)是臨時(shí)表大小的限制,由其中這兩個(gè)參數(shù)最小的決定,臨時(shí)表最大可是多少。 group by? 或者? order by 排序的時(shí)候,會(huì)產(chǎn)生臨時(shí)表。或者explain的時(shí)候,看到Using temporary的時(shí)候。 臨時(shí)表只是在這個(gè)session起作用。

max_connections?? #控制允許的最大連接數(shù)


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容