輕鬆優化MySQL-之資料庫引數優化
最佳實踐
使用InnoDB儲存引擎
InnoDB引擎已經在多方面超越了MyIsam引擎,沒有特殊需求的情況下建議選擇InnoDB引擎。
讓InnoDB使用全部記憶體
innodb_buffer_pool_size引數指定了 InnoDB 可以使用的記憶體總量。
建議設定為實體記憶體的 80%,因為要給作業系統留有空間。
如果你的記憶體是 32GB,可以設定為大約 25GB
innodb_buffer_pool_size = 25600M
注意:
(1)如果值小於1GB,說明真的應該升級伺服器了
(2)如果記憶體特別大,例如200gb,就不必給作業系統留 20% 了,因為OS用不了 40gb。
讓InnoDB多例項
innodb_buffer_pool_size的值大於 1G時,innodb_buffer_pool_instances會把 InnoDB 的快取池劃分成多個例項。
多個緩衝池的好處:
多個執行緒同時訪問緩衝池時可能會遇到瓶頸,而多個緩衝池則可以最小化這個衝突
官方建議的 buffer 數量:每個 buffer pool 例項至少要 1G
例如記憶體為 32GB,innodb_buffer_pool_size為 25GB,那麼合適的方案就是 25600M / 24 = 1.06GB
innodb_buffer_pool_instances = 24
加大max_length_for_sort_data引數的設定
在MySQL中,排序演算法分為兩種,一是隻載入排序欄位到記憶體,排序完成後再到表中取其他欄位,二是載入所有需要的欄位到記憶體,顯然第二種節省了IO操作,所以更快。決定使用哪種演算法是通過引數max_length_for_sort_data來決定的,當所有返回欄位的最大長度小於這個引數值時,MySQL就會選擇第二種演算法,反之使用第一種。所以,如果有充足的記憶體讓MySQL存放須要返回的非排序欄位,就可以加大這個引數的值來讓MySQL選擇第二種排序演算法。
當記憶體不是很充裕時,不能簡單地通過強行加大上面的引數來強迫MySQL去使用高效演算法,否則可能會造成MySQL不得不將資料分成很多段,然後進行排序,這樣可能會得不償失,此時就須要去掉不必要的返回欄位,讓返回結果長度適應max_length_for_sort_data引數的限制。
增大sort_buffer_size引數設定
增大sort_buffer_size並不是為了讓 MySQL選擇第二種排序演算法,而是為了讓MySQL儘量減少在排序過程中對須要排序的資料進行分段,因為分段會造成MySQL不得不使用臨時表來進行交換排序。
開啟查詢快取
充分利用Mysql的查詢快取機制,業務中很多SQL都會重複執行的,當然現在很多資料層框架中也有快取功能,但資料層框架中的快取屬於應用級別的,在資料被外部更新時會導致快取資料過期問題。
案例
發現網站頁面開啟非常慢,對處理過程簡單記錄了一下。
找問題
首先登入伺服器使用 top 檢視當前程序資訊,發現排名第一的是 mysql,佔用 cpu 達到了 100% 以上,這就明確了是 mysql 的問題。
登入 mysql,使用 show processlist 檢視下當前執行狀態,發現了大量 LOCK 操作,也有多個 Copying to tmp table 的操作,說明有 sql 出現了問題,操作過於複雜,對臨時表使用頻繁,把其他操作阻塞了。
解決思路
找到了問題後,把處理方向確定為檢查和修改配置、sql優化。
修改mysql配置
臨時表
既然涉及了到了臨時表,就先檢視下目前臨時表的資訊
檢視臨時表的使用狀態
show global status like 'created_tmp%';
發現 created_tmp_disk_tables 值過高,需要增加此值。
再看一下現在臨時表的大小
show variables like '%tmp_table_size%';
在現在值的基礎上增加一些,重新設定臨時表大小
執行緒快取數
看當前執行緒情況
show global status like 'Thread%';
發現 threads_created 的值過大,表明MySQL伺服器一直在建立執行緒
檢視當前值
show variables like 'thread_cache_size';
此引數需要調高
開啟表數量
檢視開啟表的情況
show global status like 'open%tables%';
發現 opened_tables 數量過大,說明 table_cache 的值可能太小。
檢視當前值
show variables like 'table_cache';
此引數需要調高
最大連線數
檢視當前允許的最大連線數
show variables like 'max_connections';
檢視伺服器連線數的峰值
show global status like 'Max_used_connections';
峰值還沒到最大限制,不需要修改
join buffer 和 sort buffer
檢視現有值
SELECT @@sort_buffer_size; SELECT @@join_buffer_size;
是預設值,需要修改
修改配置
確定了要修改的引數後,修改 my.cnf ,例如
table_cache = 64 sort_buffer_size = 8M join_buffer_size = 4M thread_cache_size = 300 thread_concurrency = 8 tmp_table_size = 246M
sql優化
從 show processlist 結果集中找出主要的複雜語句,對其進行 explain 和 profile 分析,進行索引優化,把複雜的sql 根據業務拆分為多個小的sql。