1. 程式人生 > >什麼影響了MySQL效能

什麼影響了MySQL效能

影響效能的幾個因素

  1. 伺服器硬體(CPU、記憶體、磁碟I/O等)
  2. 伺服器系統
  3. 資料庫儲存引擎的選擇
  4. 資料庫引數的配置
  5. 資料庫結構設計和SQL語句

伺服器硬體

CPU

  • 64位的CPU一定要工作在64位的系統下
  • 對於併發比較高的 場景,CPU的數量比頻率重要
  • 對於密集型場景和複雜SQL,則CPU頻率越高越好

記憶體

  • 選擇主機板所能使用的最高頻率的記憶體
  • 記憶體的大小對於效能很重要,所以儘可能的大

I/O子系統

  • PCIe -> SSD ->Raid10 ->磁碟 ->SAN

伺服器系統

優先選擇Linux

CentOS系統引數優化

sysctl.conf 優化

編輯核心相關引數

vim /etc/sysctl.conf 
  • 1
  • 2

調整配置檔案內容

//   etc/sysctl.conf 
//以下引數根據需求調整
net.core.somaxconn = 65535 //每個埠最大的監聽佇列長度
net.core.netdev_max_backlog =  65535 
net.ipv4.tcp_max_syn_backlog = 65535 


net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 10

//調整tcp連線緩衝區的預設值和最大值
net.core.wmem_default = 87380
net.core.rmem_default = 87380 net.core.rmem_max = 16777216 net.core.wmem_max = 16777216 //用於減少失效tcp連線佔用的資源,加快資源回收的效率 net.ipv4.tcp_keepalive_time = 120 net.ipv4.tcp_keepalive_intvl = 30 net.ipv4.tcp_keepalive_probes = 3 //Linux核心中最重要的引數之一,用於定義單個共享記憶體段的最大值 //注意: //1、這個引數應該設定為足夠大,以便能在一個共享記憶體段下容納下整個Innodb緩衝池的大小
//2、這個值的大小對於64位Linux系統,可取的最大值為實體記憶體值減 -1 byte,建議值為大於實體記憶體的一半,一般取值大於Innodb緩衝池的大小即可,可以取實體記憶體減 -1 byte kernel.shmmax = 4294967295 //這個引數當記憶體不足時,會對效能產生比較明顯的影響 //設定為0表示:告訴Linux核心除非虛擬記憶體完全佔滿了,否則不要使用交換分割槽swap vm.swappiness = 0
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

limit.conf引數優化

增加資源限制(/etc/security/limits.conf),這個檔案實際上是Linux PAM,也就是插入式認證模組的配置檔案。開啟檔案數的限制

vim /etc/security/limits.conf
  • 1
 #加到/etc/security/limits.conf   檔案末尾
 * soft nofile 65535
 * hard nofile 65535
 * soft nproc 65535
 * hard nproc 65535
  • 1
  • 2
  • 3
  • 4
  • 5

這裡寫圖片描述

這裡寫圖片描述

磁碟排程策略

檢視當前使用的排程策略

這裡寫圖片描述

NOOP排程策略

這裡寫圖片描述

Deadline排程策略

這種策略適用於資料庫

這裡寫圖片描述

anticipatory排程策略
這裡寫圖片描述

修改排程策略
如下為將排程策略修改為deadline策略
這裡寫圖片描述

#操作日誌
#檢視當前系統的磁碟
[root@fu020 block]# df -l
Filesystem     1K-blocks     Used Available Use% Mounted on
/dev/xvda1      20641404 10335756   9257124  53% /
tmpfs            4029028        0   4029028   0% /dev/shm
/dev/xvdb1     103210940 81019216  16948916  83% /hotdata
#檢視當前排程策略
[root@fu020 block]# cat /sys/block/xvdb/queue/scheduler 
noop anticipatory deadline [cfq] 
[root@fu020 block]# cat /sys/block/xvda/queue/scheduler 
noop anticipatory deadline [cfq] 
#修改當前排程策略
[root@fu020 block]# echo deadline > /sys/block/xvdb/queue/scheduler 
[root@fu020 block]# echo deadline > /sys/block/xvda/queue/scheduler 
[root@fu020 block]# cat /sys/block/xvda/queue/scheduler 
noop anticipatory [deadline] cfq 
[root@fu020 block]# 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

檔案系統對效能的影響

windows下有:

  • FAT
  • NTFS

Linux下有:

  • EXT3
  • EXT4
  • XFS(最好,centos7已經預設採用)

EXT3/4需要注意的地方
這裡寫圖片描述

資料庫儲存引擎的選擇

這裡寫圖片描述

MyIsam

mysql5.5版本之前的預設儲存引擎
1、Myisam儲存引擎由MYD(資料)和 MYI(索引檔案)組成,frm檔案儲存表結構(所以儲存引擎都有)

  • myisam的特性:

    1. 併發性和鎖級別 (對於讀寫混合的操作不好,為表級鎖,寫入和讀互斥)
    2. 表損壞修復
    3. myisam表支援的索引型別(全文索引…)
    4. myisam支援表壓縮(壓縮後,此表為只讀,不可以寫入。使用myisampack壓縮)
check table tablename 
repair table tablename 
#修復myisam表還有一個命令,myisamchk ,在命令列使用這個命令,需要將資料庫停止,否則可能會造成更大的表損害
  • 1
  • 2
  • 3
  • myisam的限制:
    這裡寫圖片描述

  • myisam適用場景:

    1. 非事務性應用
    2. 只讀類應用
    3. 空間類應用(唯一支援空間函式的引擎)

Innodb

Mysql5.5及之後版本的預設儲存引擎

  • Innodb使用表空間進行資料儲存

當引數 innodb_file_per_table
ON時,採用獨立表空間:tablename.id
OFF時,採用系統表空間:ibdataX,生成一個ibdata1的檔案

mysql> SHOW VARIABLES LIKE 'innodb_file_per_table';
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| innodb_file_per_table | OFF   |
+-----------------------+-------+
1 row in set (0.00 sec)

mysql> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 獨立表空間和系統表空間應該如何抉擇呢?

兩者比較:

  • 系統表空間無法簡單的收縮大小(這很恐怖,會導致ibdata1一直增大,即使刪除了資料也不會變小)
  • 獨立表空間,可以通過optimize table 命令收縮系統檔案
  • 系統表空間會產生I/O瓶頸(因為只有一個檔案)
  • 獨立表空間可以向多個檔案重新整理資料

總結
強烈建議:對Innodb引擎使用獨立表空間(mysql5.6版本以後預設是獨立表空間)

系統錶轉移為獨立表的步驟(非常繁瑣):

  • 使用mysqldump匯出所有資料庫表資料
  • 停止mysql服務,修改引數,並且刪除Innodb相關檔案
  • 重啟mysql服務,重建mysql系統表空間
  • 重新匯入資料

Innodb儲存引擎特性

  1. Innodb為事務性儲存引擎
  2. 完全支援事物的ACID特性
  3. Redo log (實現事務的永續性) 和Undo log(為了實現事務的原子性,儲存未完成事務log,用於回滾)
  4. Innodb支援行級鎖
  5. 行級鎖可以最大程度的支援併發
  6. 行級鎖是由儲存引擎層實現的

什麼是鎖

  1. 鎖的主要作用是管理共享資源的併發訪問
  2. 鎖用於實現事務的隔離性

鎖的型別

  1. 共享鎖(也稱為讀鎖)
  2. 獨佔鎖(也成為為寫鎖,排他的)
  3. 讀鎖和讀鎖是相容的 這裡寫圖片描述

鎖的粒度

  1. 表級鎖
  2. 行級鎖

阻塞和死鎖

什麼是阻塞
什麼是死鎖

Innodb狀態檢查

mysql> SHOW ENGINE INNODB STATUS;
  • 1
  • 2

使用場景
Innodb適合於大多數OLTP(線上處理)0應用

MySQL常用儲存引擎之CSV

檔案系統儲存特點

  1. 資料以文字方式儲存在檔案中
  2. .csv檔案儲存表內容
  3. .csm檔案儲存表的元資料,如表狀態和資料量
  4. .frm儲存表的結構

CSV儲存引擎特點

  1. 以CSV格式進行資料儲存
  2. 所有列 必須都是不能為NULL
  3. 不支援索引
  4. 可以對資料檔案直接編輯(其他引擎是二進位制儲存,不可編輯)

CSV適用場景

這裡寫圖片描述

MySQL常用儲存引擎之Archive

Archive儲存引擎特點

  1. 以zlib對錶資料進行壓縮,磁碟I/O更少
  2. 資料儲存在ARZ為字尾的檔案中(表文件為a.arz,a.frm)
  3. 只支援insert 和 select 操作(不可以delete 和update,會提示沒有這個功能)
  4. 只允許在自增ID列上加索引

Archive適用場景
日誌和資料採集類應用

MySQL常用儲存引擎之Memory

Memory儲存引擎特點
也稱為HEAP儲存引擎,所以資料儲存在記憶體中(資料庫重啟後會導致資料丟失)

  1. 支援HASH索引(等值查詢應選擇HASH)和BTree索引(範圍查詢應選擇)
  2. 所有欄位都為固定長度,varchar(10) == char(10)
  3. 不支援BLOG和TEXT等大欄位
  4. Memory儲存使用表級鎖(效能可能不如innodb)
    5.最大大小由 max_heap_table_size 引數決定
  5. Memory儲存引擎預設表大小隻有16M,可以通過調整max_heap_table_size 引數

Memory儲存引擎與臨時表

Memory儲存引擎和臨時表是不同概念

這裡寫圖片描述

Memory適用場景

這裡寫圖片描述

MySQL常用儲存引擎之Federated

Federated儲存引擎特點

  1. 提供了訪問遠端mysql伺服器上表的方法
  2. 本地不儲存資料,資料全部放在遠端伺服器上

使用 Federated
預設是禁止的。如果需要啟用,需要在啟動時增加Federated引數

如何選擇儲存引擎

參考條件:

  1. 是否需要事務
  2. 是否可以熱備份
  3. 崩潰恢復
  4. 儲存引擎的特有特性

重要一點:不要混合使用儲存引擎
強烈推薦: Innodb

MySQL伺服器引數介紹

Mysql獲取配置資訊

  1. 命令列引數,比如 mysql_safe --datadir = /data/sql_data (不推薦在命令列指定)
  2. 配置檔案,檢視配置檔案的
//檢視 MySQL 配置檔案載入順序
mysqld  --verbose --help | grep -A 1 'Default options'

//載入順序
/etc/my.cnf /etc/mysql/my.cnf /usr/etc/my.cnf ~/.my.cnf 
  • 1
  • 2
  • 3
  • 4
  • 5

Mysql配置引數的作用域

  1. 全域性引數
//下面兩種設定全域性引數的方式是等價的
set global 引數名 = 引數值 

set @@global.引數名 := 引數值 
  • 1
  • 2
  • 3
  • 4
  1. 會話引數
//下面兩種設定會話引數的方式是等價的
set [session] 引數名 = 引數值 ;

set @@session.引數名 := 引數值 ;
  • 1
  • 2
  • 3
  • 4

為Mysql配置記憶體相關引數

  1. 確定可以使用的記憶體上限(這裡要注意了,32位系統最多隻能使用4G記憶體,所以我們要選擇64位作業系統)
  2. 確定Mysql上的每個連線使用的記憶體
//以下引數都是為單個連線配置的
sort_buffer_size //排序緩衝區的記憶體,這個值不能過大,
join_buffer_size //連線緩衝區的記憶體,關聯多張表 ,這個值也不能太大
read_buffer_size //
read_rnd_buffer_size
  • 1
  • 2
  • 3
  • 4
  • 5

3.確定需要為作業系統保留多少記憶體 (資料庫伺服器應該單獨配置,不合程式檔案放在一個伺服器)
4. 如何為快取池分配記憶體

#不僅要快取索引而且要快取資料,Innodb嚴重依賴快取池,應該分配足夠多的記憶體給這個引數
#分配值參考公式:總記憶體 - (每個執行緒所需要的記憶體 * 連線數)- 系統保留記憶體
innodb_buffer_pool_size  


#key_buffer_size對MyISAM表效能影響很大.如果全是Innodb表,則不需要分配太大,夠系統表用即可
#查詢myisam表索引佔用的空間大小:
# select sum(index_length) from information_schema.tables where engine = 'myisam'
key_buffer_size
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

為Mysql配置IO相關引數

Innodb I/o相關配置

innodb_log_file_size #控制單個事務日誌大小
innodb_log_file_in_group #控制事務檔案個數(這個引數可以不用管它,不是越多越好)
#事務日誌總大小
# innodb_log_file_in_group  * innodb_log_file_size 

innodb_log_buffer_size #事務日誌的緩衝區大小

#0:表示每秒進行一次log寫入cache,並flush log 到磁碟(不安全)
#1【預設】:在每次事務提交執行log寫入cache,並flush log到磁碟(效率最低,最安全)
#2【建議】:每次事務提交,執行log資料寫入到cache,每秒執行一次flush log 到磁碟
innodb_flush_log_at_trx_commit = 2

#innodb重新整理的方式,影響innodb讀取資料的方式
innodb_flush_method = O_DIRECT #O_DIRECT 為Linux的最好選擇

#控制innodb如何使用表空間,為1表示為每個表建立單獨的表空間,為0表示使用系統表空間,強烈建議設定為1
innodb_file_per_table = 1 

innodb_doublewrite = 1 #使用雙寫快取,建議啟用,為了安全
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

Myisam I/o相關配置

delay_key_write
#OFF : 每次寫操作後重新整理鍵緩衝中的髒塊到磁碟
#ON  :只對建表時指定了delay_key_write選項的表使用延遲重新整理
#ALL :對所有Myisam表都使用延遲鍵寫入 
  • 1
  • 2
  • 3
  • 4

Mysql安全相關配置引數

expire_logs_days = 7 #指定自動清理binlog的天數,建議設定為7天
max_allowed_packet = 32M #控制mysql可以接收包的大小,建議32M,主從都需配置一樣大小
skip-name-resolve #禁用DNS查詢,建議啟用

#以下主要針對從庫中配置
sysdate_is_now #確保sysdate返回確定性日期
read_only #禁止非super 許可權的使用者寫入
skip_slave_start #禁用slave自動恢復(不安全的崩潰,自動恢復可能是不安全的)

#設定mysql使用的SQL模式
#sql_mode
strict_trans_tables
no_engine_subtitution
no_zero_date
no_zero_in_date
only_full_group_by
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

其它常用配置引數

sync_binlog #控制Mysql如何向磁碟重新整理binlog
tmp_table_size 和 max_heap_table_size #控制記憶體臨時表的大小
max_connections #控制允許的最大連線數
  • 1
  • 2
  • 3

資料庫設計對效能的影響

  1. 過分的反正規化化為表建立太多的列
  2. 過分的正規化化造成太多的表關聯
  3. 在OLTP環境中使用不恰當的分割槽表
  4. 使用外來鍵保證資料的完整性(儘量不使用外來鍵約束)

總結

效能優化順序

  1. 首先優化資料庫結構設計和SQL語句
  2. 選擇合理的儲存引擎和引數配置(不要混合使用儲存引擎)
  3. 系統選擇和優化
  4. 硬體升級

參考連結: