【性能優(yōu)化】MySQL性能優(yōu)化之存儲(chǔ)引擎調(diào)優(yōu)

1 MySQL總體架構(gòu)介紹

1.1 MySQL總體架構(gòu)介紹

引言
MySQL是一個(gè)關(guān)系型數(shù)據(jù)庫(kù)
應(yīng)用十分廣泛
在學(xué)習(xí)任何一門知識(shí)之前
對(duì)其架構(gòu)有一個(gè)概括性的了解是非常重要的
比如索引、sql是在哪個(gè)地方執(zhí)行的
流程是什么樣的
今天我們就先來(lái)學(xué)習(xí)一下MySQL的總體架構(gòu)

總的來(lái)說(shuō):MySQL架構(gòu)是一個(gè)客戶端-服務(wù)器系統(tǒng)。

file

MySQL主要包括以下幾部分:

Server 層:主要包括連接器、查詢緩存、分析器、優(yōu)化器、執(zhí)行器等,所有跨存儲(chǔ)引擎的功能都在這一層實(shí)現(xiàn),比如存儲(chǔ)過(guò)程、觸發(fā)器、視圖,函數(shù)等,還有一個(gè)通用的日志模塊 binglog 日志模塊。

存儲(chǔ)引擎: 主要負(fù)責(zé)數(shù)據(jù)的存儲(chǔ)和讀取,采用可以替換的插件式架構(gòu),支持 InnoDB、MyISAM、Memory 等多個(gè)存儲(chǔ)引擎,其中 InnoDB 引擎有自己的日志模塊 redolog 模塊。現(xiàn)在最常用的存儲(chǔ)引擎是 InnoDB,它從 MySQL 5.5.5 版本開(kāi)始就被當(dāng)做默認(rèn)存儲(chǔ)引擎了

連接器: 身份認(rèn)證和權(quán)限相關(guān)(登錄 MySQL 的時(shí)候)。

查詢緩存: 執(zhí)行查詢語(yǔ)句的時(shí)候,會(huì)先查詢緩存(MySQL 8.0 版本后移除,因?yàn)檫@個(gè)功能不太實(shí)用)mysql的server層增加一層緩存模塊,類似一個(gè)內(nèi)存的kv層,k是sql,value是結(jié)果

分析器: 沒(méi)有命中緩存的話,SQL 語(yǔ)句就會(huì)經(jīng)過(guò)分析器,分析器說(shuō)白了就是要先看你的 SQL 語(yǔ)句要干嘛,再檢查你的 SQL 語(yǔ)句語(yǔ)法是否正確。

優(yōu)化器: 按照 MySQL 認(rèn)為最優(yōu)的方案去執(zhí)行。

執(zhí)行器: 執(zhí)行語(yǔ)句,然后從存儲(chǔ)引擎返回?cái)?shù)據(jù)。

1.2 MySQL存儲(chǔ)引擎介紹

引言
和大多數(shù)的數(shù)據(jù)庫(kù)不同, MySQL中有一個(gè)存儲(chǔ)引擎的概念

針對(duì)不同的存儲(chǔ)需求可以選擇最優(yōu)的存儲(chǔ)引擎。

存儲(chǔ)引擎就是存儲(chǔ)數(shù)據(jù),建立索引,更新查詢數(shù)據(jù)等等技術(shù)的實(shí)現(xiàn)方式 。

存儲(chǔ)引擎是基于表的,而不是基于庫(kù)的
所以存儲(chǔ)引擎也可被稱為表類型。

MySQL提供了插件式的存儲(chǔ)引擎架構(gòu)。所以MySQL存在多種存儲(chǔ)引擎,可以根據(jù)需要使用相應(yīng)引擎,或者編寫存儲(chǔ)引擎。

MySQL5.0支持的存儲(chǔ)引擎包含 : InnoDB 、MyISAM 、BDB、MEMORY、MERGE、EXAMPLE、NDB Cluster、ARCHIVE、CSV、BLACKHOLE、FEDERATED等

可以通過(guò)指定 show engines , 來(lái)查詢當(dāng)前數(shù)據(jù)庫(kù)支持的存儲(chǔ)引擎 :

SHOW ENGINES;
file
表含義:
  - support : 指服務(wù)器是否支持該存儲(chǔ)引擎
  - transactions : 指存儲(chǔ)引擎是否支持事務(wù)
  - XA : 指存儲(chǔ)引擎是否支持分布式事務(wù)處理
  - Savepoints : 指存儲(chǔ)引擎是否支持保存點(diǎn)(實(shí)現(xiàn)回滾到指定保存點(diǎn))
  • 查看MySQL數(shù)據(jù)庫(kù)存儲(chǔ)引擎配置

    SHOW VARIABLES LIKE '%storage_engine%';
    
file

1.2.1 如何更改數(shù)據(jù)庫(kù)表引擎

  • 建表語(yǔ)句后面加入引擎賦值即可 ,命令舉例如下 ,
CREATE TABLE t1(
    id INT ,
    name VARCHAR(20)
) ENGINE = MyISAM;

  • 修改已有的表引擎 , 命令舉例如下 ,
ALTER TABLE t1 ENGINE = InnoDB;

1.2.2 常用引擎及其特性對(duì)比

  • 常見(jiàn)的存儲(chǔ)引擎 :

    MyISAM存儲(chǔ)引擎 : 訪問(wèn)快,不支持事務(wù)和外鍵。表結(jié)構(gòu)保存在.frm文件中,表數(shù)據(jù)保存在.MYD文件中,索引保存在.MYI文件中。

    [root@linux-141 itcast]# ll
    -rw-r-----. 1 mysql mysql       8630 9月  10 16:01 t_account_myisam.frm
    -rw-r-----. 1 mysql mysql         52 9月  10 16:06 t_account_myisam.MYD
    -rw-r-----. 1 mysql mysql       2048 9月  10 17:56 t_account_myisam.MYI
    [root@linux-141 itcast]#
    
    
file

innoDB存儲(chǔ)引擎(5.5版本開(kāi)始默認(rèn)) : 支持事務(wù) ,占用磁盤空間大 ,支持并發(fā)控制。表結(jié)構(gòu)保存在.frm文件中,如果是共享表空間,數(shù)據(jù)和索引保存在 innodb_data_home_dir 和 innodb_data_file_path定義的表空間中,可以是多個(gè)文件。如果是多表空間存儲(chǔ),每個(gè)表的數(shù)據(jù)和索引單獨(dú)保存在 .ibd 中。

[root@linux-141 itcast]# ll
-rw-r-----. 1 mysql mysql       8630 9月  10 16:02 t_account_innodb.frm
-rw-r-----. 1 mysql mysql      98304 9月  14 15:50 t_account_innodb.ibd
[root@linux-141 itcast]#
file

MEMORY存儲(chǔ)引擎 : 內(nèi)存存儲(chǔ) , 速度快 ,不安全 ,適合小量快速訪問(wèn)的數(shù)據(jù)。表結(jié)構(gòu)保存在.frm中。

!
file

特性對(duì)比 :

特點(diǎn) InnoDB MyISAM MEMORY MERGE NDB
存儲(chǔ)限制 64TB 沒(méi)有
事務(wù)安全 ==支持==
鎖機(jī)制 ==行鎖(適合高并發(fā))== ==表鎖== 表鎖 表鎖 行鎖
B樹(shù)索引 支持 支持 支持 支持 支持
哈希索引 支持
全文索引 支持(5.6版本之后) 支持
集群索引 支持
數(shù)據(jù)索引 支持 支持 支持
索引緩存 支持 支持 支持 支持 支持
數(shù)據(jù)可壓縮 支持
空間使用 N/A
內(nèi)存使用 中等
批量插入速度
支持外鍵 ==支持==

1.2.3 如何選擇不同類型的引擎

在選擇存儲(chǔ)引擎時(shí),應(yīng)該根據(jù)應(yīng)用系統(tǒng)的特點(diǎn)選擇合適的存儲(chǔ)引擎。對(duì)于復(fù)雜的應(yīng)用系統(tǒng),還可以根據(jù)實(shí)際情況選擇多種存儲(chǔ)引擎進(jìn)行組合。

以下是幾種常用的存儲(chǔ)引擎的使用環(huán)境。

  • InnoDB : 是Mysql的默認(rèn)存儲(chǔ)引擎,用于事務(wù)處理應(yīng)用程序,支持外鍵。如果應(yīng)用對(duì)事務(wù)的完整性有比較高的要求,在并發(fā)條件下要求數(shù)據(jù)的一致性,數(shù)據(jù)操作除了插入和查詢以外,還包含更新、刪除操作,那么InnoDB存儲(chǔ)引擎是比較合適的選擇。InnoDB存儲(chǔ)引擎除了有效的降低由于刪除和更新導(dǎo)致的鎖定, 還可以確保事務(wù)的完整提交和回滾,對(duì)于類似于計(jì)費(fèi)系統(tǒng)或者財(cái)務(wù)系統(tǒng)等對(duì)數(shù)據(jù)準(zhǔn)確性要求比較高的系統(tǒng),InnoDB是最合適的選擇。
  • MyISAM : 如果應(yīng)用是以讀操作和插入操作為主,只有很少的更新和刪除操作,并且對(duì)事務(wù)的完整性、并發(fā)性要求不是很高,那么選擇這個(gè)存儲(chǔ)引擎是非常合適的。
  • MEMORY:將所有數(shù)據(jù)保存在RAM中,在需要快速定位記錄和其他類似數(shù)據(jù)環(huán)境下,可以提供極快的訪問(wèn)。MEMORY的缺陷就是對(duì)表的大小有限制,太大的表無(wú)法緩存在內(nèi)存中,其次是要確保表的數(shù)據(jù)可以恢復(fù),數(shù)據(jù)庫(kù)異常終止后表中的數(shù)據(jù)是可以恢復(fù)的。MEMORY表通常用于更新不太頻繁的小表,用以快速得到訪問(wèn)結(jié)果。

1.3 SQL的執(zhí)行流程是什么樣的

  • 客戶端發(fā)送一條查詢給服務(wù)器。
  • 服務(wù)器先檢查查詢緩存,如果命中了緩存,則立刻返回存儲(chǔ)在緩存中的結(jié)果。否則進(jìn)入下一階段。
  • 服務(wù)器端進(jìn)行SQL解析、預(yù)處理,再由優(yōu)化器生成對(duì)應(yīng)的執(zhí)行計(jì)劃。
  • MySQL根據(jù)優(yōu)化器生成的執(zhí)行計(jì)劃,再調(diào)用存儲(chǔ)引擎的API來(lái)執(zhí)行查詢。
  • 將結(jié)果返回給客戶端。
file

2 MySQL存儲(chǔ)引擎調(diào)優(yōu)

2.1 MySQL服務(wù)器硬件優(yōu)化

tips

硬件(cpu、內(nèi)存等)相關(guān)

了解即可

關(guān)于提升硬件設(shè)備性能:

例如選擇盡量高頻率的內(nèi)存(頻率不能高于主板的支持)、提升網(wǎng)絡(luò)帶寬、使用SSD高速磁盤、提升CPU性能等。

CPU的選擇:

  • 對(duì)于數(shù)據(jù)庫(kù)并發(fā)比較高的場(chǎng)景,CPU的數(shù)量比頻率重要。
  • 對(duì)于CPU密集型場(chǎng)景和頻繁執(zhí)行復(fù)雜SQL的場(chǎng)景,CPU的頻率越高越好

磁盤的選擇

影響數(shù)據(jù)庫(kù)最大的性能問(wèn)題就是磁盤I/O
為提高數(shù)據(jù)庫(kù)的IOPS性能,可使用SSD或PCIE-SSD高速磁盤設(shè)備

磁盤IO的優(yōu)化

可以用RAID來(lái)進(jìn)行優(yōu)化

常用RAID(磁盤陣列)級(jí)別:

RAID0:也稱為條帶,就是把多個(gè)磁盤鏈接成一個(gè)硬盤使用,這個(gè)級(jí)別IO最好
RAID1:也稱為鏡像,要求至少有兩個(gè)磁盤,每組磁盤存儲(chǔ)的數(shù)據(jù)相同
RAID5:也是把多個(gè)(最少3個(gè))硬盤合并成一個(gè)邏輯盤使用,數(shù)據(jù)讀寫時(shí)會(huì)建立奇偶校驗(yàn)信息,并且奇偶校驗(yàn)信息和相對(duì)應(yīng)的數(shù)據(jù)分別存儲(chǔ)在不同的磁盤上。當(dāng)RAID5的一個(gè)磁盤數(shù)據(jù)發(fā)生損壞后,利用剩下的數(shù)據(jù)和響應(yīng)的奇偶校驗(yàn)信息去恢復(fù)被損壞的數(shù)據(jù)

RAID1+0(建議使用):就是RAID0和RAID1的組合。同時(shí)具備兩個(gè)級(jí)別的優(yōu)缺點(diǎn),一般建議數(shù)據(jù)庫(kù)使用這個(gè)級(jí)別。

2.2 MySQL數(shù)據(jù)庫(kù)配置優(yōu)化

tips:

以下為生產(chǎn)環(huán)境中最常用的DB參數(shù)配置

  • 表示緩沖池字節(jié)大小,大的緩沖池可以減少磁盤IO次數(shù)。
    innodb_buffer_pool_size = 推薦值為物理內(nèi)存的50%~80%。
  • 用來(lái)控制redo log buffer刷新到磁盤的策略。
    innodb_flush_log_at_trx_commit=1

    select @@innodb_flush_log_at_trx_commit;
    
    0 : 提交事務(wù)的時(shí)候,不立即把 redo log buffer 里的數(shù)據(jù)刷入磁盤文件中,而是依靠 InnoDB 的主線程每秒執(zhí)行一次刷新到磁盤。此時(shí)可能你提交事務(wù)了,結(jié)果 mysql 宕機(jī)了,然后此時(shí)內(nèi)存里的數(shù)據(jù)全部丟失。
    1 : 提交事務(wù)的時(shí)候,立即把 redo log buffer 里的數(shù)據(jù)刷入磁盤文件中,只要事務(wù)提交成功,那么數(shù)據(jù)就必然在磁盤里了。
    2 : 提交事務(wù)的時(shí)候,把 redo log buffer日志寫入磁盤文件對(duì)應(yīng)的系統(tǒng)緩存,而不是直接進(jìn)入磁盤文件,這時(shí)可能1秒后才會(huì)把系統(tǒng)緩存里的數(shù)據(jù)寫入到磁盤文件。
    
  • 每提交1次事務(wù)就同步寫到磁盤中,可以設(shè)置為1。
    sync_binlog=1

    0:默認(rèn)值。事務(wù)提交后,將二進(jìn)制日志從緩沖寫入操作系統(tǒng)緩沖,但是不進(jìn)行刷新操作(fsync()),此時(shí)只是寫入了操作系統(tǒng)緩沖而沒(méi)有刷新到磁盤,若操作系統(tǒng)宕機(jī)則會(huì)丟失部分二進(jìn)制日志。
    1:事務(wù)提交后,將二進(jìn)制文件寫入磁盤并立即執(zhí)行刷新操作,相當(dāng)于是同步寫入磁盤,不經(jīng)過(guò)操作系統(tǒng)的緩存。
    N:每寫N次操作系統(tǒng)緩沖就執(zhí)行一次刷新操作。
    
  • 臟頁(yè)占innodb_buffer_pool_size的比例,觸發(fā)刷臟頁(yè)到磁盤。 推薦值為25%~50%。
    innodb_max_dirty_pages_pct=30

    臟頁(yè):內(nèi)存數(shù)據(jù)頁(yè)和磁盤數(shù)據(jù)頁(yè)上的內(nèi)容不一致
    
  • 后臺(tái)進(jìn)程最大IO性能指標(biāo)。
    默認(rèn)200,如果SSD,調(diào)整為5000~20000

    PCIE-SSD可調(diào)整為5w左右

    默認(rèn):innodb_io_capacity=200

  • 指定innodb共享表空間文件的大小。
    innodb_data_file_path = ibdata:1G:autoextend:默認(rèn)10M,

    一般設(shè)置為1GB

  • 慢查詢?nèi)罩镜拈撝翟O(shè)置,單位秒。
    long_query_time=0.3

    合理設(shè)置區(qū)間0.1s~0.5s,

  • mysql復(fù)制的形式,row為MySQL8.0的默認(rèn)形式。
    binlog_format=row

    建議binlog的記錄格式為row模式

    STATEMENT模式:每一條會(huì)修改數(shù)據(jù)的sql語(yǔ)句都會(huì)記錄到binlog中。
    ROW模式:不記錄每條sql語(yǔ)句的上下文信息,僅需記錄哪條數(shù)據(jù)被修改了,修改成什么樣了。
    MIXED模式:以上兩種模式的混合使用。
    
  • 降低interactive_timeout、wait_timeout的值。

    交互等待時(shí)間和非交互等待時(shí)間,值一致,建議300~500s,默認(rèn)8小時(shí)

    在用mysql客戶端對(duì)數(shù)據(jù)庫(kù)進(jìn)行操作時(shí),打開(kāi)終端窗口,如果一段時(shí)間(8小時(shí))沒(méi)有操作,再次操作時(shí),會(huì)報(bào)錯(cuò):當(dāng)前的連接已經(jīng)斷開(kāi),需要重新建立連接
    
  • 數(shù)據(jù)庫(kù)最大連接數(shù)max_connections=200
  • 過(guò)大,實(shí)例恢復(fù)時(shí)間長(zhǎng);過(guò)小,造成日志切換頻繁。
    innodb_log_file_size=默認(rèn)

    redo log空間大小

  • 全量日志建議關(guān)閉。
    默認(rèn)關(guān)閉general_log=0

    開(kāi)啟 general log 將所有到達(dá)MySQL Server的SQL語(yǔ)句記錄下來(lái),general_Log文件就會(huì)產(chǎn)生很大的文件,建議關(guān)閉
    

2.3 Mysql中查詢緩存優(yōu)化

tips:

在MySQL 8.0之后廢棄這個(gè)功能

原理:復(fù)雜、實(shí)用性不高

作為了解即可

1) 查詢緩存概述

開(kāi)啟Mysql的查詢緩存,當(dāng)執(zhí)行完全相同的SQL語(yǔ)句的時(shí)候,服務(wù)器就會(huì)直接從緩存中讀取結(jié)果,當(dāng)數(shù)據(jù)被修改,之前的緩存會(huì)失效,修改比較頻繁的表不適合做查詢緩存。

2) 操作流程

回顧

file
  1. 客戶端發(fā)送一條查詢給服務(wù)器;
  2. 服務(wù)器先會(huì)檢查查詢緩存,如果命中了緩存,則立即返回存儲(chǔ)在緩存中的結(jié)果。否則進(jìn)入下一階段;
  3. 服務(wù)器端進(jìn)行SQL解析、預(yù)處理,再由優(yōu)化器生成對(duì)應(yīng)的執(zhí)行計(jì)劃;
  4. MySQL根據(jù)優(yōu)化器生成的執(zhí)行計(jì)劃,調(diào)用存儲(chǔ)引擎的API來(lái)執(zhí)行查詢;
  5. 將結(jié)果返回給客戶端。

3) 查詢緩存配置

  1. 查看當(dāng)前的MySQL數(shù)據(jù)庫(kù)是否支持查詢緩存:

    SHOW VARIABLES LIKE 'have_query_cache';  
    
file
  1. 查看當(dāng)前MySQL是否開(kāi)啟了查詢緩存 :

    SHOW VARIABLES LIKE 'query_cache_type';
    
file
  1. 查看查詢緩存的占用大小 :

    SHOW VARIABLES LIKE 'query_cache_size';
    
file
  1. 查看查詢緩存的狀態(tài)變量:

    SHOW STATUS LIKE 'Qcache%';
    
file

各個(gè)變量的含義如下:

參數(shù) 含義
Qcache_free_blocks 查詢緩存中的可用內(nèi)存塊數(shù)
Qcache_free_memory 查詢緩存的可用內(nèi)存量
Qcache_hits 查詢緩存命中數(shù)
Qcache_inserts 添加到查詢緩存的查詢數(shù)
Qcache_lowmen_prunes 由于內(nèi)存不足而從查詢緩存中刪除的查詢數(shù)
Qcache_not_cached 非緩存查詢的數(shù)量(由于 query_cache_type 設(shè)置而無(wú)法緩存或未緩存)
Qcache_queries_in_cache 查詢緩存中注冊(cè)的查詢數(shù)
Qcache_total_blocks 查詢緩存中的塊總數(shù)

4) 開(kāi)啟查詢緩存

MySQL的查詢緩存默認(rèn)是關(guān)閉的,需要手動(dòng)配置參數(shù) query_cache_type , 來(lái)開(kāi)啟查詢緩存。query_cache_type 該參數(shù)的可取值有三個(gè) :

含義
OFF 或 0 查詢緩存功能關(guān)閉
ON 或 1 查詢緩存功能打開(kāi),SELECT的結(jié)果符合緩存條件即會(huì)緩存,否則,不予緩存,顯式指定 SQL_NO_CACHE,不予緩存
DEMAND 或 2 查詢緩存功能按需進(jìn)行,顯式指定 SQL_CACHE 的SELECT語(yǔ)句才會(huì)緩存;其它均不予緩存

在 my.cnf 配置中,增加以下配置 :

#開(kāi)啟查詢緩存
query_cache_type=1

配置完畢之后,重啟服務(wù)既可生效 ;

然后就可以在命令行執(zhí)行SQL語(yǔ)句進(jìn)行驗(yàn)證 ,執(zhí)行一條比較耗時(shí)的SQL語(yǔ)句,然后再多執(zhí)行幾次,查看后面幾次的執(zhí)行時(shí)間;獲取通過(guò)查看查詢緩存的緩存命中數(shù),來(lái)判定是否走查詢緩存。

-- 執(zhí)行SQL語(yǔ)句進(jìn)行驗(yàn)證 查詢緩存
SELECT * FROM product_list WHERE store_name = '聯(lián)想北達(dá)興科專賣店';
-- 將SELECT修改為小寫,發(fā)現(xiàn)緩存失效
SELECT * FROM product_list WHERE store_name = '聯(lián)想北達(dá)興科專賣店';

5) 查詢緩存SELECT選項(xiàng)

可以在SELECT語(yǔ)句中指定兩個(gè)與查詢緩存相關(guān)的選項(xiàng) :

SQL_CACHE : 如果查詢結(jié)果是可緩存的,并且 query_cache_type 系統(tǒng)變量的值為ON或 DEMAND ,則緩存查詢結(jié)果 。

SQL_NO_CACHE : 服務(wù)器不使用查詢緩存。它既不檢查查詢緩存,也不檢查結(jié)果是否已緩存,也不緩存查詢結(jié)果。

例子:

SELECT SQL_CACHE id, name FROM xxx;
SELECT SQL_NO_CACHE id, name FROM xxx;

6) 查詢緩存失效的情況

tips

需要注意的問(wèn)題

1) SQL 語(yǔ)句不一致的情況, 要想命中查詢緩存,查詢的SQL語(yǔ)句必須一致。

SQL1 : select count(*) from xxx;
SQL2 : Select count(*) from xxx;

2) 當(dāng)查詢語(yǔ)句中有一些不確定的值,則不會(huì)緩存。如 : now() , current_date() , curdate() , curtime() , rand() , uuid() , user() , database() 。

SQL1 : select * from xxx where updatetime < now() limit 1;
SQL2 : select user();
SQL3 : select database();

3) 不使用任何表查詢語(yǔ)句。

select 'A';

4) 查詢 mysql, information_schema或 performance_schema 數(shù)據(jù)庫(kù)中的表時(shí),不會(huì)走查詢緩存。

select * from information_schema.engines;

5) 在存儲(chǔ)的函數(shù),觸發(fā)器或事件的主體內(nèi)執(zhí)行的查詢。

6) 如果表更改,則使用該表的所有高速緩存查詢都將變?yōu)闊o(wú)效并從高速緩存中刪除。這包括使用MERGE映射到已更改表的表的查詢。一個(gè)表可以被許多類型的語(yǔ)句,如被改變 INSERT, UPDATE, DELETE, TRUNCATE TABLE, ALTER TABLE, DROP TABLE,或 DROP DATABASE 。

將查詢緩存關(guān)閉,因?yàn)楹竺孢€需要進(jìn)行索引的驗(yàn)證,所以不希望走查詢緩存

[root@linux-141 itcast]# vi /etc/my.cnf
[root@linux-141 itcast]# service mysql restart
Shutting down MySQL.... SUCCESS!
Starting MySQL. SUCCESS!

2.4. Mysql內(nèi)存管理及優(yōu)化

1)內(nèi)存優(yōu)化原則

1) 將盡量多的內(nèi)存分配給MySQL做緩存,但要給操作系統(tǒng)和其他程序預(yù)留足夠內(nèi)存。

2) MyISAM 存儲(chǔ)引擎的數(shù)據(jù)文件讀取依賴于操作系統(tǒng)自身的IO緩存,因此,如果有MyISAM表,就要預(yù)留更多的內(nèi)存給操作系統(tǒng)做IO緩存。

3) 排序區(qū)、連接區(qū)等緩存是分配給每個(gè)數(shù)據(jù)庫(kù)會(huì)話(session)專用的,其默認(rèn)值的設(shè)置要根據(jù)最大連接數(shù)合理分配,如果設(shè)置太大,不但浪費(fèi)資源,而且在并發(fā)連接較高時(shí)會(huì)導(dǎo)致物理內(nèi)存耗盡。

2) MyISAM 內(nèi)存優(yōu)化

MyISAM 存儲(chǔ)引擎使用 key_buffer 緩存索引塊,加速myisam索引的讀寫速度。對(duì)于myisam表的數(shù)據(jù)塊,mysql沒(méi)有特別的緩存機(jī)制,完全依賴于操作系統(tǒng)的IO緩存。

key_buffer_size

key_buffer_size決定MyISAM索引塊緩存區(qū)的大小,直接影響到MyISAM表的存取效率。可以在MySQL參數(shù)文件中設(shè)置key_buffer_size的值,對(duì)于一般MyISAM數(shù)據(jù)庫(kù),建議至少將1/4可用內(nèi)存分配給key_buffer_size。

在my.cnf 中做如下配置:

key_buffer_size=512M
read_buffer_size

如果需要經(jīng)常順序掃描MyISAM 表,可以通過(guò)增大read_buffer_size的值來(lái)改善性能。但需要注意的是read_buffer_size是每個(gè)session獨(dú)占的,如果默認(rèn)值設(shè)置太大,就會(huì)造成內(nèi)存浪費(fèi)。

read_rnd_buffer_size

對(duì)于需要做排序的MyISAM 表的查詢,如帶有order by子句的sql,適當(dāng)增加 read_rnd_buffer_size 的值,可以改善此類的sql性能。

但需要注意的是 read_rnd_buffer_size 是每個(gè)session獨(dú)占的,如果默認(rèn)值設(shè)置太大,就會(huì)造成內(nèi)存浪費(fèi)。

3) InnoDB 內(nèi)存優(yōu)化

innodb用一塊內(nèi)存區(qū)做IO緩存池,該緩存池不僅用來(lái)緩存innodb的索引塊,而且也用來(lái)緩存innodb的數(shù)據(jù)塊。

innodb_buffer_pool_size

該變量決定了 innodb 存儲(chǔ)引擎表數(shù)據(jù)和索引數(shù)據(jù)的最大緩存區(qū)大小。在保證操作系統(tǒng)及其他程序有足夠內(nèi)存可用的情況下,innodb_buffer_pool_size 的值越大,緩存命中率越高,訪問(wèn)InnoDB表需要的磁盤I/O 就越少,性能也就越高。

innodb_buffer_pool_size=512M
innodb_log_buffer_size

決定了innodb重做日志緩存的大小,對(duì)于可能產(chǎn)生大量更新記錄的大事務(wù),增加innodb_log_buffer_size的大小,可以避免innodb在事務(wù)提交前就執(zhí)行不必要的日志寫入磁盤操作。

innodb_log_buffer_size=10M

2.5. Mysql并發(fā)參數(shù)調(diào)整

從實(shí)現(xiàn)上來(lái)說(shuō),MySQL Server 是多線程結(jié)構(gòu),包括后臺(tái)線程和客戶服務(wù)線程。多線程可以有效利用服務(wù)器資源,提高數(shù)據(jù)庫(kù)的并發(fā)性能。在Mysql中,控制并發(fā)連接和線程的主要參數(shù)包括 max_connections、back_log、thread_cache_size、table_open_cahce。

1) max_connections

最大可支持的連接數(shù)

采用max_connections 控制允許連接到MySQL數(shù)據(jù)庫(kù)的最大數(shù)量,默認(rèn)值是 151。如果狀態(tài)變量 connection_errors_max_connections 不為零,并且一直增長(zhǎng),則說(shuō)明不斷有連接請(qǐng)求因數(shù)據(jù)庫(kù)連接數(shù)已達(dá)到允許最大值而失敗,這時(shí)可以考慮增大max_connections 的值。

Mysql 最大可支持的連接數(shù),取決于很多因素,包括給定操作系統(tǒng)平臺(tái)的線程庫(kù)的質(zhì)量、內(nèi)存大小、每個(gè)連接的負(fù)荷、CPU的處理速度,期望的響應(yīng)時(shí)間等。在Linux 平臺(tái)下,性能好的服務(wù)器,支持 500-1000 個(gè)連接不是難事,需要根據(jù)服務(wù)器性能進(jìn)行評(píng)估設(shè)定。

2) back_log

積壓請(qǐng)求棧大小

back_log 參數(shù)控制MySQL監(jiān)聽(tīng)TCP端口時(shí)設(shè)置的積壓請(qǐng)求棧大小。如果MySql的連接數(shù)達(dá)到max_connections時(shí),新來(lái)的請(qǐng)求將會(huì)被存在堆棧中,以等待某一連接釋放資源,該堆棧的數(shù)量即back_log,如果等待連接的數(shù)量超過(guò)back_log,將不被授予連接資源,將會(huì)報(bào)錯(cuò)。5.6.6 版本之前默認(rèn)值為 50 , 之后的版本默認(rèn)為 50 + (max_connections / 5), 但最大不超過(guò)900。

如果需要數(shù)據(jù)庫(kù)在較短的時(shí)間內(nèi)處理大量連接請(qǐng)求, 可以考慮適當(dāng)增大back_log 的值。

3) table_open_cache

執(zhí)行線程可打開(kāi)表緩存?zhèn)€數(shù)

該參數(shù)用來(lái)控制所有SQL語(yǔ)句執(zhí)行線程可打開(kāi)表緩存的數(shù)量, 而在執(zhí)行SQL語(yǔ)句時(shí),每一個(gè)SQL執(zhí)行線程至少要打開(kāi) 1 個(gè)表緩存。該參數(shù)的值應(yīng)該根據(jù)設(shè)置的最大連接數(shù) max_connections 以及每個(gè)連接執(zhí)行關(guān)聯(lián)查詢中涉及的表的最大數(shù)量來(lái)設(shè)定 :

max_connections x N ;

4) thread_cache_size

緩存客戶服務(wù)線程的數(shù)量

為了加快連接數(shù)據(jù)庫(kù)的速度,MySQL 會(huì)緩存一定數(shù)量的客戶服務(wù)線程以備重用,通過(guò)參數(shù) thread_cache_size 可控制 MySQL 緩存客戶服務(wù)線程的數(shù)量。

5)lock_wait_timeout

innodb_lock_wait_timeout

事務(wù)等待行鎖的時(shí)間

該參數(shù)是用來(lái)設(shè)置InnoDB 事務(wù)等待行鎖的時(shí)間,默認(rèn)值是50ms , 可以根據(jù)需要進(jìn)行動(dòng)態(tài)設(shè)置。對(duì)于需要快速反饋的業(yè)務(wù)系統(tǒng)來(lái)說(shuō),可以將行鎖的等待時(shí)間調(diào)小,以避免事務(wù)長(zhǎng)時(shí)間掛起; 對(duì)于后臺(tái)運(yùn)行的批量處理程序來(lái)說(shuō), 可以將行鎖的等待時(shí)間調(diào)大, 以避免發(fā)生大的回滾操作。

本文由育博學(xué)谷狂野架構(gòu)師發(fā)布
如果本文對(duì)您有幫助,歡迎關(guān)注和點(diǎn)贊;如果您有任何建議也可留言評(píng)論或私信,您的支持是我堅(jiān)持創(chuàng)作的動(dòng)力
轉(zhuǎn)載請(qǐng)注明出處!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容