MySQL優化方向&思路

硬件級別

        操作系統和硬件級別的優化着眼點

1、對於CPU密集型的應用場景要使用更快速度的CPU甚至更多數量的CPU,爲有着更多查詢的場景使用更多的CPU等。基於多核以及超線程(hyperthreading)技術,現代的CPU架構越來越複雜、性能也越來越強了,但MySQL對多CPU架構的並行計算能力的利用仍然是有着不太盡如人意之處,尤其是較老的版本如MySQL 5.1之前的版本甚至無法發揮多CPU的優勢。不過,通常需要實現的CPU性能提升目標有兩類:低遲延和高吞吐量。低延遲需要更快速度的CPU,因爲單個查詢只能使用一顆;而需要同時運行許多查詢的場景,多CPU更能提供更好的吞吐能力,然而其能否奏效還依賴於實際工作場景,因爲MySQL尚不能高效的運行於多CPU,並且其對CPU數量的支持也有着限制。一般來說,較新的版本可以支持16至24顆CPU甚至更多。

2、是否有着合適大小的物理內存,並通過合理的配置平衡內存和磁盤資源,降低甚至避免磁盤I/O。現代的程序設計爲提高性能通常都會基於局部性原理使用到緩存技術,這對於頻繁操作數據的數據庫系統來說尤其如此——有着良好設計的數據庫緩存通常比針對通用任務的操作系統的緩存效率更高。緩存可以有效地延遲寫入、優化寫入,但並能消除寫入,並綜合考慮存儲空間的可擴展性等,爲業務選擇合理的外部存儲設備也是非常重要的工作。

3、是否選擇了合適的網絡設備並正確地配置了網絡對整體系統系統也有着重大影響。延遲和帶寬是網絡連接的限制性因素,而常見的網絡問題如丟包等,即是很小的丟包率也會贊成性能的顯著下降。而更重要的還有按需調整系統中關網絡方面的設置,以高效處理大量的連接和小查詢。

4、是否基於操作系統選擇了適用的文件系統。實際測試表明大部分文件系統的性能都非常接近,因此,爲了性能而苦選文件系統並不划算。但考慮到文件系統的修復能力,應該使用日誌文件系統如ext3、ext4、XFS等。同時,關閉文件系統的某些特性如訪問時間和預讀行爲,並選擇合理的磁盤調度器通常都會給性能提升帶來幫助。

5、MySQL爲響應每個用戶連接使用一個單獨的線程,再加內部使用的線程、特殊目的線程以及其它任何由存儲引擎創建的線程等,MySQL需要對這些大量線程進行有效管理。Linux系統上的NPTL線程庫更爲輕量級也更有效率。MySQL 5.5引入了線程池插件,但其效用尚不明朗。

來源:網絡

OS級別

        優化腳本(針對Centos 6.x)

#!/bin/bash
# Authotby:Tommy.Gandolf
#
# Add SwapFile
Mem=$(free -m |awk '/Mem:/{print $2}')
Swap=$(free -m |awk '/Swap:/{print $2}')
if ["$Swap" == 0 ]; then
        if [ $Mem -le 1024 ]; then
                dd if=/dev/zero of=/swapfilecount=1024 bs=1M
                mkswap /swapfile
                swapon /swapfile
                chmod 600 /swapfile
        elif [ $Mem -gt 1024 -a $Mem -le 2048]; then
                dd if=/dev/zero of=/swapfilecount=2048 bs=1M
                mkswap /swapfile
                swapon /swapfile
                chmod 600 /swapfile
        fi
cat >>/etc/fstab << EOF
/swapfile    swap   swap    defaults    0 0
EOF
 
fi
 
# Install neededpackages
for Package in gccgcc-c++ make cmake autoconf libjpeg libjpeg-devel libpng libpng-devel freetypefreetype-devel libxml2 libxml2-devel zlib zlib-devel glibc glibc-devel glib2glib2-devel bzip2 bzip2-devel ncurses ncurses-devel libaio curl curl-devele2fsprogs e2fsprogs-devel krb5-devel libidn libidn-devel openssl openssl-devellibxslt-devel libevent-devel libtool libtool-ltdl bison gd-devel vim-enhancedpcre-devel zip unzip ntpdate sysstat patch bc expect rsync git
do
        yum -y install $Package
done
 
yum -y update bashopenssl glibc
 
if [ -n "`gcc--version | head -n1 | grep '4.4'`" ]; then
        yum install gcc44 gcc44-c++libstdc++44-devel
        export CC="gcc44"CXX="g++44"
fi
 
# Close AndRemoved Services
for Service in `chkconfig--list | grep 3:on | awk '{print $1}'`;do chkconfig --level 3 $Service off;done
for Service insshd network crond iptables messagebus irqbalance syslog rsyslog; do chkconfig--level 3 $Service on; done
 
# Colse SELINUX
sed -i's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
 
#Modify PS1
export PS1='\[\033[0;31m\]\342\224\214\342\224\200$([[ $? != 0 ]] &&echo"[\[\033[0;31m\]\342\234\227\[\033[0;37m\]]\342\224\200")[\[\033[01;31m\]root\[\033[01;33m\]@\[\033[01;96m\]\h\[\033[0;31m\]]\342\224\200[\[\033[0;32m\]\w\[\033[0;31m\]]\n\[\033[0;31m\]\342\224\224\342\224\200\342\224\200\342\225\274\[\033[0m\]\[\e[01;33m\]\$\[\e[0m\]'
 
# history size 
sed -i's/^HISTSIZE=.*$/HISTSIZE=100/' /etc/profile
 
# Descriptor fileSymbol
ulimit -SHn 65535
echo '*  - nofile  65535' >>/etc/security/limits.conf
echo  'ulimit -SHn 65535' >> /etc/rc.local
echo 'ulimit  -s 65535' >> /etc/rc.local
 
# Update systemtime_zone
yum install lrzzsntpdate sysstat -y
echo '*/5 * * * *root /usr/sbin/ntpdate time.windows.com > /dev/null 2>&1' >>/var/spool/cron/root
echo '*/10 * * * *root /usr/sbin/ntpdate time.nist.gov > /dev/null 2>&1' >>/var/spool/cron/root
 
# Cchange defaultsshd port
sed -i '/#Port22/s/#Port 22/Port 65535/' /etc/ssh/sshd_config
#sed -i '/#PermitRootLoginyes/s/#PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
sed -i'/#PermitEmptyPasswords no/s/#PermitEmptyPasswords no/PermitEmptyPasswords no/'/etc/ssh/sshd_config
sed -i '/#UseDNSyes/s/#UseDNS yes/UseDNS no/' /etc/ssh/sshd_config
service sshdrestart
 
# User add sudopower
/usr/sbin/useradd adminroot
echo'1q2w3e4r' | passwd --stdin adminroot  && history -c
sed -i'108a\leerwjamesmengroot   ALL=(ALL)       NOPASSWD: ALL'/etc/sudoers
# Empty iptablesrules
echo '*/5 * * * *root /etc/init.d/iptables  stop' >>/etc/crontab
/etc/init.d/crond  restart
iptables -F -t nat
iptables -X
iptables -P INPUTDROP
iptables -P OUTPUTACCEPT
iptables -PFORWARD ACCEPT
 
modprobeiptable_nat
modprobe ip_conntrack_ftp
modprobeip_nat_ftp
 
iptables -A INPUT-i lo -j ACCEPT
iptables -A OUTPUT-o lo -j ACCEPT
iptables -A INPUT-m state --state ESTABLISHED,RELATED -j ACCEPT
 
iptables -A INPUT-m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
iptables -A INPUT-m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
iptables -A INPUT-m state --state NEW -m tcp -p tcp --dport 65535 -j ACCEPT
iptables -Nsynflood
iptables -Asynflood -m limit --limit 10/s --limit-burst 100 -j RETURN
iptables -Asynflood -p tcp -j REJECT --reject-with tcp-reset
iptables -A INPUT-p tcp -m state --state NEW -j synflood
iptables -A INPUT-p icmp --icmp-type echo-request -m limit --limit 1/s --limit-burst 5 -j ACCEPT
iptables -A INPUT-p icmp --icmp-type echo-request -j DROP
service iptablessave
service iptablesrestart
 
# Lock file systemimpotant
chattr +i/etc/passwd
chattr +i/etc/inittab
chattr +i/etc/group
chattr +i/etc/shadow
chattr +i/etc/gshadow
# Rename chattrword
mv /usr/bin/chattr/usr/bin/mvchattr
# Hide systemversion information
:>/etc/redhat-release 
:> /etc/issue
# Optimize thekernel parameters
cat >>/etc/sysctl.conf <<EOF
net.ipv4.tcp_fin_timeout= 2
net.ipv4.tcp_tw_reuse= 1
net.ipv4.tcp_tw_recycle= 1
net.ipv4.tcp_syncookies= 1
net.ipv4.tcp_keepalive_time=600
net.ipv4.ip_local_port_range= 4000    65000
net.ipv4.tcp_max_syn_backlog= 16384
net.ipv4.tcp_max_tw_buckets= 36000
net.ipv4.route.gc_timeout= 100
net.ipv4.tcp_syn_retries= 1
net.ipv4.tcp_synack_retries= 1
net.core.somaxconn= 16384
net.core.netdev_max_backlog= 16384
net.ipv4.tcp_max_orphans= 16384
EOF
sysctl  -p
echo "SystemSecurity init OK"
echo "InitSystem OK.... "

MySQL級別

        安裝優化

使用jemalloc內存管理替代操作系統本身的內存管理機制

tar jxvfjemalloc-3.4.0.tar.bz2
cd jemalloc-3.4.0
./configure
make && makeinstall
echo'/usr/local/lib' >> /etc/ld.so.conf.d/local.conf
ldconfig  -v > /dev/null 2>&1
groupadd  -r mysql
useradd  -g mysql -r -s /sbin/nologin  -M mysql
tar zxvfmysql-5.5.43.tar.gz
cd mysql-5.5.43
cmake . -DCMAKE_INSTALL_PREFIX=/usr/local/mysql\
-DMYSQL_DATADIR=/data/mydata\
-DSYSCONFDIR=/etc\
-DWITH_INNOBASE_STORAGE_ENGINE=1\
-DWITH_PARTITION_STORAGE_ENGINE=1\
-DWITH_FEDERATED_STORAGE_ENGINE=1\
-DWITH_BLACKHOLE_STORAGE_ENGINE=1\
-DWITH_MYISAM_STORAGE_ENGINE=1\
-DWITH_ARCHIVE_STORAGE_ENGINE=1\
-DWITH_READLINE=1\
-DENABLED_LOCAL_INFILE=1\
-DENABLE_DTRACE=0\
-DDEFAULT_CHARSET=utf8\
-DDEFAULT_COLLATION=utf8_general_ci\
-DWITH_EMBEDDED_SERVER=1\
-DCMAKE_EXE_LINKER_FLAGS='-ljemalloc' \
-DWITH_SAFEMALLOC=OFF
make -j `grepprocessor /proc/cpuinfo | wc -l`
make install
 
sed -i's@executing mysqld_safe@executing mysqld_safe\nexportLD_PRELOAD=/usr/local/lib/libjemalloc.so@' $MYSQL_INSTALL_DIR/bin/mysqld_safe
# lsof -n | grepjemalloc

wKiom1W0lfPjr7vHAADzFGHELVo715.jpg

        配置優化

cat >/etc/my.cnf << EOF
[client]
port = 3306
socket =/tmp/mysql.sock
 
[mysqld]
port = 3306
socket =/tmp/mysql.sock
 
basedir =/usr/local/mysql
datadir =/data/mydata
pid-file =/data/mydata/mysql.pid
user = mysql
bind-address =0.0.0.0
server-id = 1
 
skip-name-resolve
#skip-networking
back_log = 300
 
max_connections =1000
max_connect_errors= 6000
open_files_limit =65535
table_open_cache =128 
max_allowed_packet= 4M
binlog_cache_size= 1M
max_heap_table_size= 8M
tmp_table_size =16M
 
read_buffer_size =2M
read_rnd_buffer_size= 8M
sort_buffer_size =8M
join_buffer_size =8M
key_buffer_size =4M
 
thread_cache_size= 8
 
query_cache_type =1
query_cache_size =8M
query_cache_limit= 2M
 
ft_min_word_len =4
 
log_bin =mysql-bin
binlog_format =mixed
expire_logs_days =30
 
log_error =/data/mydata/mysql-error.log
slow_query_log = 1
long_query_time =1
slow_query_log_file= /data/mydata/mysql-slow.log
 
performance_schema= 0
 
#lower_case_table_names= 1
 
skip-external-locking
 
default_storage_engine= InnoDB
#default-storage-engine= MyISAM
innodb_file_per_table= 1
innodb_open_files= 500
innodb_buffer_pool_size= 64M
innodb_write_io_threads= 4
innodb_read_io_threads= 4
innodb_thread_concurrency= 0
innodb_purge_threads= 1
innodb_flush_log_at_trx_commit= 2
innodb_log_buffer_size= 2M
innodb_log_file_size= 32M
innodb_log_files_in_group= 3
innodb_max_dirty_pages_pct= 90
innodb_lock_wait_timeout= 120
 
bulk_insert_buffer_size= 8M
myisam_sort_buffer_size= 8M
myisam_max_sort_file_size= 10G
myisam_repair_threads= 1
 
interactive_timeout= 28800
wait_timeout =28800
 
[mysqldump]
quick
max_allowed_packet= 16M
 
[myisamchk]
key_buffer_size =8M
sort_buffer_size =8M
read_buffer = 4M
write_buffer = 4M
EOF

        依據內存調整配置參數

腳本內容如下:

#!/bin/bash
# Author by:Tommy.Gandolf
#
Memtatol=`free -m| grep 'Mem:' | awk '{print $2}'`
if [ $Memtatol -gt1500 -a $Memtatol -le 2500 ];then
        sed -i's@^thread_cache_size.*@thread_cache_size = 16@' /etc/my.cnf
        sed -i's@^query_cache_size.*@query_cache_size = 16M@' /etc/my.cnf
        sed -i's@^myisam_sort_buffer_size.*@myisam_sort_buffer_size = 16M@' /etc/my.cnf
        sed -i's@^key_buffer_size.*@key_buffer_size = 16M@' /etc/my.cnf
        sed -i's@^innodb_buffer_pool_size.*@innodb_buffer_pool_size = 128M@' /etc/my.cnf
        sed -i 's@^tmp_table_size.*@tmp_table_size= 32M@' /etc/my.cnf
        sed -i's@^table_open_cache.*@table_open_cache = 256@' /etc/my.cnf
elif [ $Memtatol-gt 2500 -a $Memtatol -le 3500 ];then
        sed -i's@^thread_cache_size.*@thread_cache_size = 32@' /etc/my.cnf
        sed -i's@^query_cache_size.*@query_cache_size = 32M@' /etc/my.cnf
        sed -i's@^myisam_sort_buffer_size.*@myisam_sort_buffer_size = 32M@' /etc/my.cnf
elif [ $Memtatol-gt 3500 ];then
        sed -i 's@^thread_cache_size.*@thread_cache_size= 64@' /etc/my.cnf
        sed -i's@^query_cache_size.*@query_cache_size = 64M@' /etc/my.cnf
        sed -i's@^myisam_sort_buffer_size.*@myisam_sort_buffer_size = 64M@' /etc/my.cnf
        sed -i's@^key_buffer_size.*@key_buffer_size = 256M@' /etc/my.cnf
        sed -i's@^innodb_buffer_pool_size.*@innodb_buffer_pool_size = 1024M@' /etc/my.cnf
        sed -i's@^tmp_table_size.*@tmp_table_size = 128M@' /etc/my.cnf
        sed -i's@^table_open_cache.*@table_open_cache = 1024@' /etc/my.cnf
fi
 
echo " "

        安全優化

#!/bin/bash
# Author by:Tommy.Gandolf
#
MYSQL_INSTALL_DIR=/usr/local/mysql
DBPASSWD=123456
$MYSQL_INSTALL_DIR/bin/mysql-e "grant all privileges on *.* to root@'127.0.0.1' identified by \"DBPASSWD\"with grant option;"
$MYSQL_INSTALL_DIR/bin/mysql-e "grant all privileges on *.* to root@'localhost' identified by \"DBPASSWD\"with grant option;"
$MYSQL_INSTALL_DIR/bin/mysql-uroot -pDBPASSWD -e "delete from mysql.user where Password='';"
$MYSQL_INSTALL_DIR/bin/mysql-uroot -pDBPASSWD -e "delete from mysql.db where User='';"
$MYSQL_INSTALL_DIR/bin/mysql-uroot -pDBPASSWD -e "delete from mysql.proxies_priv whereHost!='localhost';"
$MYSQL_INSTALL_DIR/bin/mysql-uroot -pDBPASSWD -e "drop database test;"
$MYSQL_INSTALL_DIR/bin/mysql-uroot -pDBPASSWD -e "reset master;"
echo “ ”

MySQL5.5新特性調整

MySQL5.1之前innodb的格式是AntelopeMySQL5.5 innodb插件的格式調整爲Barracuda,支持表壓縮功能,TRUNCATE TABLE速度更快。

官方innodb參數如下:

innodb_purge_threads=1
innodb_file_format=barracuda
innodb-buffer-pool-size=8192M
innodb_support_xa=FALSE
innodb_flush_method=O_DIRECT
innodb-flush-log-at-trx-commit=2
innodb-log-file-size=2000M
innodb-log-buffer-size=64M
innodb-io-capacity=200
skip-innodb-adaptive-hash-index
innodb-read-io-threads=8
innodb-write-io-threads=8
innodb_change_buffering=all
innodb_stats_on_metadata=off
innodb-buffer-pool-instances=12
skip-grant-tables
max_tmp_tables=100
query_cache_size=0
query_cache_type=0
max_connections=1000
max_prepared_stmt_count=1048576
sort_buffer_size=32768

利用CPU的多核處理功能

innodb_read_io_threads= 8
innodb_write_io_threads= 8

提高刷新髒頁數量和合並插入數量,改善磁盤IO處理能力

SET GLOBAL innodb_io_capacity = 2000;

參考如下:

innodb_io_capacity磁盤配置

200                   單盤SAS/SATA

2000                    SAS*12 RAID10

5000                    SSD

50000                  FUSION-IO


增加了自適應刷新髒頁功能

innodb_adaptive_flushing

加快了InnoDB的數據恢復時間

innodb_log_file_size= 300M
innodb_log_files_in_group= 3
innodb_log_buffer_size= 16M
innodb_max_dirty_pages_pct= 75
innodb_force_recovery= 0
innodb_buffer_pool_size= 600M
innodb_flush_log_at_trx_commit= 0

INNODB 同時支持多個BufferPool實例

innodb_buffer_pool_instances= 3

提高了默認innodb線程併發數

innodb_thread_concurrency= 0

改善清除程序進度

innodb_purge_batch_size=5000

添加了刪除緩衝和清除緩衝

SET GLOBALinnodb_change_buffering = all;

控制自旋鎖Spin Lock輪訓間隔

set globalinnodb_spin_wait_delay=6;

InnoDB支持創建壓縮數據頁

innodb_file_format= Barracuda
innodb_file_per_table= 1

在建表的時候加入ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8 即可,如:

CREATE TABLE`compressed` (
`id` int(10)unsigned NOT NULL AUTO_INCREMENT,
37 / 65
`k` int(10)unsigned NOT NULL DEFAULT '0',
`c` char(120) NOTNULL DEFAULT '',
`pad` char(60) NOTNULL DEFAULT '',
PRIMARY KEY(`id`),
KEY `k` (`k`)
) ENGINE=InnoDB
DEFAULTCHARSET=gbk
ROW_FORMAT=COMPRESSED
KEY_BLOCK_SIZE=8

可動態關閉InnoDB更新元數據統計功能

set globalinnodb_stats_on_metadata = OFF;

中繼日誌relay-log自我修復

relay_log_recovery= 1(在slave上設置)

開啓InnoDB嚴格檢查模式

set globalinnodb_strict_mode=1;

支持動態更改InnoDB鎖超時時間

set globalinnodb_lock_wait_timeout = 10;


show status\G;工具優化


1.慢查詢

showvariables like ‘slow%’; #查看是否開啓了慢查詢,以及慢查詢的日誌文件

wKioL1W0mmDTIMnvAAGT3y3LDyY863.jpg


Show global statuslike ‘slow%’; #查看mysql的慢查詢運行狀態信息

wKioL1W0mpKDXh4yAAD67VeInRs199.jpg


配置中打開了記錄慢查詢,執行時間超過2秒的即爲慢查詢,如果slow_queries顯示爲4148,那麼,系統顯示有4148個慢查詢,你可以分析慢查詢日誌,找出有問題的sql語句,慢查詢時間不宜設置過長,否則意義不大,最好在5秒以內,如果你需要微秒級別的慢查詢,可以考慮給mysql打補丁:http://www.percona.com /docs/wiki/release:start,記得找對應的版本。

 

打開慢查詢日誌可能會對系統性能有一點點影響,如果你的mysql是主-從結構,可以考慮打開其中一臺從服務器的慢查詢日誌,這樣既可以監控慢查詢,對系統性能影響又小


2.連接數

經常會遇見”mysql:error 1040: too many connections”的情況,一種是訪問量確實很高,mysql服務器抗不住,這個時候就要考慮增加從服務器分散讀壓力,另外一種情況是mysql 置文件中max_connections值過小:

wKioL1W0mtrztLPxAADhZ2pv7xI669.jpg

連接mysql的最大連接數是151,然後查詢一下服務器響應的最大連接數

Show global statuslike ‘max_used_connections’

wKioL1W0mvTC3HhLAAEBA8_uGng429.jpg

Mysql過去的最大連接數是19個,並沒有達到151的上限,應該是不會出現1404的錯誤設置,最合理的設置:

max_used_connections / max_connections * 100% = 85%

最大連接數占上限數的85%左右,如果發現比列在10%一下,如果在10%一下,mysql的連接數設置過高了。

這裏的計算:19/max_connections*100%=85% max_connections=23纔對
如果按照這裏的151計算: 19/151 * 100% = 12.5% 不算高

3.key_buffer_size


key_buffer_size是對myisam表性能影響最大的一個參數

show variableslike ‘key_buffer_size’;

wKiom1W0mV_z0wzAAAD5ZivohcQ470.jpg

這裏看得出來,key_buffer_size分配了16M的內存大小,我們再查詢下key_buffer_size的內存使用情況:

show global statuslike ‘key_read%’;

wKioL1W0m4CyH4LAAAD2k__o2Is811.jpg

一共有110236個索引讀取請求,有2720個請求在內存中沒有找到,直接從硬盤服務器硬盤讀取索引,計算索引爲命中的概率爲:

Key_cache_miss_rate= key_reads / key_read_requests * 100%

Key_cache_miss_rate= 2720/ 110236 * 100%=2.4%

比如上面的數據,key_cache_miss_rate2.4%,如果key_cache_miss_rate 0.01%以下的話,key_buffer_size分配的過多,可以適當減少

Mysql的服務器還提供了key_blocks_* 的參數:

Show global statuslike ‘key_blocks_u%’;

wKiom1W0mdGQIF8WAAEbzL_I0RI926.jpg

key_blocks_unused 表示未使用的緩存簇(blocks)數,key_blocks_used表示曾經用到的最大的blocks數,比如這臺服務器,所有的緩存都用到了,要麼 增加key_buffer_size,要麼就是過渡索引了,把緩存佔滿了。比較理想的設置:

key_blocks_ued / key_blocks_unused + key_blocks_used * 100%=80%

這裏計算的結果:58/13374 + 58= 0.43%

4.臨時表

Show global statuslike ‘create_tmp%’;

wKiom1W0mgzhvPe9AAFHOiI-VCA867.jpg

每次創建臨時表,created_tmp_tables增加,如果是在磁盤上創建臨時表,created_tmp_disk_tables也增加,created_tmp_files表示mysql服務創建的臨時文件文件數,比較理想的配置是:

created_tmp_disk_tables/ created_tmp_tables * 100% <= 25%比如上面的服務器created_tmp_disk_tables /created_tmp_tables * 100% 60%,就需要優化了。我們再看一下mysql服務器對臨時表的配置:

show variableswhere variable_name in (‘tmp_table_size’,’max_heap_table_size’);

wKiom1W0mjmS2hFEAAE4dhBbyQE400.jpg

只有256mb以下的臨時表才能全部放內存,超過的就會用到硬盤臨時表

5.open table 情況

Show globalstatuslike ‘open%tables%’;

wKioL1W0nFrTjizBAAD5B6EHm3Q922.jpg

open_tables表示打開表的數量,opened_tables表示打開過的表數量,如果opened_tables數量過大,說明配置中 table_cache(5.1.3之後這個值叫做table_open_cache)值可能太小,我們查詢一下服務器table_cache值:

show variableslike 'table_open_cache';

wKioL1W0nIaDoxVqAADv-dnYsd0532.jpg

比較合適的設置爲:

Open_tables /opend_tables * 100% >= 85%

Open_tables /tables_cache * 100%>= 95%

這裏的值分別計算爲:87% 和76%

6.進程使用情況

Show global statuslike ‘thread%’;


wKiom1W0mtbx4v-FAAEo8svaylY123.jpg

如果我們在mysql服務器配置文件中設置了thread_cache_size,當客戶端斷開之後,服務器處理此客戶的線程將會緩存起來以響應下一個客 戶而不是銷燬(前提是緩存數未達上限)。threads_created表示創建過的線程數,如果發現threads_created值過大的話,表明mysql服務器一直在創建線程,這也是比較耗資源,可以適當增加配置文件中thread_cache_size值,查詢服務器 thread_cache_size配置:

Show variableslike ‘thread_cache_size’;

wKiom1W0mwSRs3hBAADjx-8BQaE846.jpg

7.查詢緩存(query cache

Show global statuslike ‘qcache%’;

wKiom1W0m0PjYYyfAAGw2M0gC7k894.jpg

mysql查詢緩存變量解釋:

qcache_free_blocks:緩存中相鄰內存塊的個數。數目大說明可能有碎片。flush query cache會對緩存中的碎片進行整理,從而得到一個空閒塊。

qcache_free_memory:緩存中的空閒內存。

qcache_hits:每次查詢在緩存中命中時就增大

qcache_inserts:每次插入一個查詢時就增大。命中次數除以插入次數就是不中比率。

qcache_lowmem_prunes 緩存出現內存不足並且必須要進行清理以便爲更多查詢提供空間的次數。這個數字最好長時間來看;如果這個數字在不斷增長,就表示可能碎片非常嚴重,或者內存 很少。(上面的free_blocksfree_memory可以告訴您屬於哪種情況)

qcache_not_cached:不適合進行緩存的查詢的數量,通常是由於這些查詢不是 select 語句或者用了now()之類的函數。

qcache_queries_in_cache:當前緩存的查詢(和響應)的數量。

qcache_total_blocks:緩存中塊的數量。

在查詢下服務器關於query_cache的配置

show  variables like 'query_cache%';

wKioL1W0nWPyY8kZAAGFfDJQWVc924.jpg

各字段的解釋:

query_cache_limit:超過此大小的查詢將不緩存

query_cache_min_res_unit:緩存塊的最小大小

query_cache_size:查詢緩存大小

query_cache_type:緩存類型,決定緩存什麼樣的查詢,示例中表示不緩存 select sql_no_cache 查詢

query_cache_wlock_invalidate:當有其他客戶端正在對myisam表進行寫操作時,如果查詢在query cache中,是否返回cache結果還是等寫操作完成再讀表獲取結果。

query_cache_min_res_unit的配置是一柄”雙刃劍”,默認是4kb,設置值大對大數據查詢有好處,但如果你的查詢都是小數據查詢,就容易造成內存碎片和浪費。

查詢緩存碎片率 = qcache_free_blocks / qcache_total_blocks * 100%

如果查詢緩存碎片率超過20%,可以用flush query cache整理緩存碎片,或者試試減小query_cache_min_res_unit如果你的查詢都是小數據量的話。

查詢緩存利用率 =(query_cache_size - qcache_free_memory) / query_cache_size * 100%

查詢緩存利用率在25%以下的話說明query_cache_size設置的過大,可適當減小;查詢緩存利用率在80%以上而且qcache_lowmem_prunes > 50的話說明query_cache_size可能有點小,要不就是碎片太多。

查詢緩存命中率 =(qcache_hits - qcache_inserts) / qcache_hits * 100%

示例服務器 查詢緩存碎片率 1.8%,查詢緩存利用率 0.6%,查詢緩存命中率 20.6%,命中率很差,可能寫操作比較頻繁吧,而且可能有些碎片

8.排序使用情況

Show global statuslike ‘sort%’;

sort_merge_passes 包括兩步。mysql 首先會嘗試在內存中做排序,使用的內存大小由系統變量 sort_buffer_size 決定,如果它的大小不夠把所有的記錄都讀到內存中,mysql 就會把每次在內存中排序的結果存到臨時文件中,等 mysql 找到所有記錄之後,再把臨時文件中的記錄做一次排序。這再次排序就會增加 sort_merge_passes。實際上,mysql 會用另一個臨時文件來存再次排序的結果,所以通常會看到 sort_merge_passes 增加的數值是建臨時文件數的兩倍。因爲用到了臨時文件,所以速度可能會比較慢,增加 sort_buffer_size 會減少 sort_merge_passes 創建臨時文件的次數。但盲目的增加 sort_buffer_size 並不一定能提高速度

9.文件打開數

Show globalstatus  like ‘open_files%’;

wKioL1W0nbnS3H5DAADuIzD3qU8639.jpg

show  variables like 'open_files_limit';

wKiom1W0m_Ty-9t4AADqmczE_DM699.jpg

比較合適的設置:open_files/ open_files_limit * 100% <= 75%

10.表鎖情況

Show global statuslike ‘table_locks%’;

wKioL1W0nhDSA9Q-AAEdJAEO4ks469.jpg

table_locks_immediate表示立即釋放表鎖數,table_locks_waited表示需要等待的表鎖數,如果 table_locks_immediate / table_locks_waited> 5000,最好採用innodb引擎,因爲innodb是行鎖而myisam是表鎖,對於高併發寫入的應用innodb效果會好些。示例中的服務器 table_locks_immediate / table_locks_waited 235myisam就足夠了。

11.表掃描情況

Show global statuslike ‘handler_read%’;

wKiom1W0nGHxfzAiAAGg_l3Rfv0982.jpg

Handler_read_first此選項表明SQL是在做一個全索引掃描,注意是全部,而不是部分,所以說如果存在WHERE語句,這個選項是不會變的。如果這個選項的數值很大,既是好事 也是壞事。說它好是因爲畢竟查詢是在索引裏完成的,而不是數據文件裏,說它壞是因爲大數據量時,簡便是索引文件,做一次完整的掃描也是很費時的

wKioL1W0nmnR1DqkAAFwmLBOnlw989.jpg

Handler_read_key此選項數值如果很高,那麼恭喜你,你的系統高效的使用了索引,一切運轉良好

wKioL1W0nqeDxkClAAHQOeHlmmY433.jpg

Handler_read_next此選項表明在進行索引掃描時,按照索引從數據文件裏取數據的次數

Handler_read_prev此選項表明在進行索引掃描時,按照索引倒序從數據文件裏取數據的次數,一般就是ORDER BY ... DESC

Handler_read_rnd簡單的說,就是查詢直接操作了數據文件,很多時候表現爲沒有使用索引或者文件排序

Handler_read_rnd_next此選項表明在進行數據文件掃描時,從數據文件裏取數據的次數

 

說到判斷查詢方式優劣這個問題,就再順便提提show profile語法,在新版MySQL裏提供了這個功能:

Set profiling=on;

Show profile;

wKiom1W0nPPQ0_FuAALGsFjwOSo030.jpg

Show profiles;

wKioL1W0nw2x31djAAEcrnZW77M294.jpg

調出服務器完成的查詢請求次數:

Show globalstatus like ‘com_select’;

wKiom1W0nVOhtqnAAADm5dFbagQ934.jpg

計算表掃描率:

表掃描率 handler_read_rnd_next / com_select

如果表掃描率超過4000,說明進行了太多表掃描,很有可能索引沒有建好,增加read_buffer_size值會有一些好處,但最好不要超過8mb


END

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章