以前一位童鞋發的:html
5版郵件,在用戶量很大的狀況下,若是作了分佈式,若是在後端mysql上執行:
mysql> show global status like 'Thread%';
Threads_cached 0
Threads_connected 793
Threads_created 2397086
Threads_running 260
看到 Threads_created 的值特別大,Threads_cached爲0,並且此時mysql鏈接數和負載特別高的狀況下,必定在my.cnf中加上以下參數:
thread_cache_size 128
先停掉各個前端,而後再重啓後端mysql.
會發現各個前端機mysql的鏈接數總和會遠小於後端mysql的鏈接數,由於鏈接都被cached掉了.
Mysql優化筆記:
從慢查詢、鏈接數、Key_buffer_size、臨時表、Open Table狀況、進程使用狀況、查詢緩存、排序使用狀況、文件打開數、表鎖狀況、表掃描狀況
這些方面去優化
====================================================================================
1. 慢查詢:
慢查詢個數: mysql> show global status like '%slow_queries';
慢查詢日誌開關: mysql> show global variables like '%log_slow_queries';
(1) 開啓慢查詢日誌:
my.cnf
long_query_time = 5 // 執行超過多久的sql會被log下來,這裏是5秒
log-slow-queries = /var/log/slowquery.log //設置把日誌寫在那裏
log-queries-not-using-indexes //紀錄沒使用索引的sql
配置後重啓 mysql。
(2) 分析日誌: mysqldumpslow
-s,是order的順序,主要有c,t,l,r和ac,at,al,ar,分別是按照query次數,時間,lock的時間和返回的記錄數來排序,前面加了a的時倒序。
-t,是top n的意思,即爲返回前面多少條的數據
-g,後邊能夠寫一個正則匹配模式,大小寫不敏感的
mysqldumpslow -s c -t 20 /var/log/slowquery.log //訪問次數最多的20個sql語句
mysqldumpslow -s t -t 20 /var/log/slowquery.log //執行時間最多的20個sql語句
mysqldumpslow -s r -t 20 /var/log/slowquery.log //返回記錄集最多的20個sql
mysqldumpslow -t 10 -s t -g "left join" /var/log/slowquery.log //這按照時間返回前10條裏面含有左鏈接的sql語句。
=================================================================================
2. 鏈接數
最大鏈接數配置: show global variables like 'max_connections';
曾用最大鏈接數: show global status like 'max_used_connections';
當前鏈接數: show global status like 'Threads_connected';
曾用來處理鏈接的線程數: show global status like 'Threads_created';
max_used_connections / max_connections * 100% (理想值 ≈ 85%)
修改最大鏈接數配置:
mysql> set GLOBAL max_connections=1000;
mysql> flush privileges
也能夠修改/etc/my.cnf中的max_connections:
max_connections = 1000
max_used_connections: The maximum number of connections that have been in use simultaneously since the server started. 從MYSQL本次開機以來,歷史數據中的最大同時的併發聯接數。
Threads_created: The number of threads created to handle connections.
========================================================================================
3. key_buffer_size
key_buffer_size是對MyISAM表性能影響最大的一個參數,Innodb表不適用。
mysql> show global variables like 'key_buffer_size';
mysql> show global status where Variable_name in ('Key_read_requests','Key_reads') ;
Key_read_requests 737517278
Key_reads 276013
mysql> select 276013/737517278*100;
0.0374
一共有737517278個索引讀取請求,有276013個請求在內存中沒有找到直接從硬盤讀取索引,計算索引未命中緩存的機率:
key_cache_miss_rate = Key_reads / Key_read_requests * 100% = 0.0374%
若是未命中機率過大,能夠適當加大key_buffer_size
mysql> show global status where Variable_name in ('key_blocks_used','key_blocks_unused');
Key_blocks_unused 131673
Key_blocks_used 217227
mysql> select 217227/(131673+217227)*100;
62.2605
Key_blocks_unused表示未使用的緩存簇(blocks)數,Key_blocks_used表示曾經用到的最大的blocks數
Key_blocks_used / (Key_blocks_unused + Key_blocks_used) * 100% ≈ 62.2605% (理想值 ≈ 80%)
========================================================================================
臨時表
mysql> show global status like 'created_tmp%';
Created_tmp_disk_tables 1
Created_tmp_files 16
Created_tmp_tables 1145
每次建立臨時表,Created_tmp_tables增長;若是是在磁盤上建立臨時表,Created_tmp_disk_tables 也增長;Created_tmp_files表示MySQL服務建立的臨時文件文件數:
Created_tmp_disk_tables / Created_tmp_tables * 100% = 0.0873% (理想值<= 25%)
mysql> show variables where Variable_name in ('tmp_table_size', 'max_heap_table_size');
max_heap_table_size 16777216
tmp_table_size 33554432
可適當增長 tmp_table_size
========================================================================================
open table 的狀況
mysql> show global status like 'open%tables%';
Open_tables 512
Opened_tables 2008
mysql> show variables like '%table_cache%';
table_cache 512
mysql> select 512/2008*100;
25.4980
mysql> select 512/512*100;
100.0000
Open_tables 表示打開表的數量,Opened_tables表示打開過的表數量。
若是Opened_tables數量過大,說明配置中 table_cache(5.1.3以後這個值叫作table_open_cache)值可能過小.
Open_tables / Opened_tables * 100% = 38.5196% 理想值 (>= 85%)
Open_tables / table_cache * 100% = 99.6094% 理想值 (<= 95%)
========================================================================================
進程使用狀況
mysql> show global status like 'Thread%';
Threads_cached 7
Threads_connected 112
Threads_created 2397
Threads_running 24
mysql> show variables like 'thread_cache_size';
thread_cache_size 64
若是咱們在MySQL服務器配置文件中設置了thread_cache_size,當客戶端斷開以後,服務器處理此客戶的線程將會緩存起來以響應下一個客戶而不是銷燬(前提是緩存數未達上限)。
Threads_created表示建立過的線程數,若是發現Threads_created值過大的話,代表 MySQL服務器一直在建立線程,這也是比較耗資源,能夠適當增長配置文件中thread_cache_size值。
========================================================================================
查詢緩存(query cache)
mysql> show global status like 'qcache%';
Qcache_free_blocks 4119
Qcache_free_memory 11911976
Qcache_hits 873527
Qcache_inserts 1267423
Qcache_lowmem_prunes 713698
Qcache_not_cached 895888
Qcache_queries_in_cache 11301
Qcache_total_blocks 27096
Qcache_free_blocks:緩存中相鄰內存塊的個數。數目大說明可能有碎片。FLUSH QUERY CACHE會對緩存中的碎片進行整理,從而獲得一個空閒塊。
Qcache_free_memory:緩存中的空閒內存。
Qcache_hits:每次查詢在緩存中命中時就增大
Qcache_inserts:每次插入一個查詢時就增大。命中次數除以插入次數就是不中比率。
Qcache_lowmem_prunes:緩存出現內存不足而且必需要進行清理以便爲更多查詢提供空間的次數。這個數字最好長時間來看;若是這個數字在不斷增加,就表示可能碎片很是嚴重,或者內存不多。(上面的 free_blocks和free_memory能夠告訴您屬於哪一種狀況)
Qcache_not_cached:不適合進行緩存的查詢的數量,一般是因爲這些查詢不是 SELECT 語句或者用了now()之類的函數。
Qcache_queries_in_cache:當前緩存的查詢(和響應)的數量。
Qcache_total_blocks:緩存中塊的數量。
咱們再查詢一下服務器關於query_cache的配置:
mysql> show variables like 'query_cache%';
query_cache_limit 1048576
query_cache_min_res_unit 4096
query_cache_size 33554432
query_cache_type ON
query_cache_wlock_invalidate OFF
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,設置值大對大數據查詢有好處,但若是你的查詢都是小數據查詢,就容易形成內存碎片和浪費。
mysql> select 4119 / 27096 *100;
15.2015
查詢緩存碎片率 = Qcache_free_blocks / Qcache_total_blocks * 100%
若是查詢緩存碎片率超過20%,能夠用FLUSH QUERY CACHE整理緩存碎片,或者試試減少query_cache_min_res_unit,若是你的查詢都是小數據量的話。
mysql> select (33554432-11911976) / 33554432 *100;
64.4995
查詢緩存利用率 = (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%
示例服務器 查詢緩存碎片率 = 20.46%,查詢緩存利用率 = 62.26%,查詢緩存命中率 = 1.94%,命中率不好,可能寫操做比較頻繁吧,並且可能有些碎片。
========================================================================================
排序使用狀況
mysql> show global status like 'sort%';
Sort_merge_passes 2
Sort_range 18528
Sort_rows 390838
Sort_scan 3439