如何提高 MySQL 伺服器性能..?
作為 MySQL DBA,大多數時候我們應該優化性能不佳的 MySQL 伺服器。
現在我的問題是從哪裡開始就像我們需要找出很多事情一樣
1.Find the duplicate indexes. 2.Find unused indexes on the basis of selectivity. 3.Monitor the Server Parameters(What should be important parameters). 4.Execute MySQL Server performance tuning script. 5.Slow logs
那麼檢查伺服器的順序應該是什麼,應該監控/分析什麼以提高性能。
查找重複索引
早在 2012 年 1 月,@gbn 回答了一個關於重複索引的問題,他在其中展示了來自Ronald Bradford 部落格的2 個視圖。我將這兩個視圖組合到一個查詢中以顯示重複索引,如下所示:
SELECT ndx1.TABLE_SCHEMA,ndx1.TABLE_NAME, CASE WHEN ndx1.COLUMNS = ndx2.COLUMNS AND (ndx1.IS_UNIQUE = ndx2.IS_UNIQUE) THEN GREATEST(ndx1.INDEX_NAME, ndx2.INDEX_NAME) ELSE ndx1.INDEX_NAME END REDUNDANT_INDEX_NAME, GROUP_CONCAT(DISTINCT CASE WHEN ndx1.COLUMNS = ndx2.COLUMNS AND (ndx1.IS_UNIQUE = ndx2.IS_UNIQUE) THEN LEAST(ndx1.INDEX_NAME, ndx2.INDEX_NAME) ELSE ndx2.INDEX_NAME END ) INDEX_NAME FROM ( SELECT TABLE_SCHEMA,TABLE_NAME,INDEX_NAME,INDEX_TYPE, IF(NON_UNIQUE, 'NO', 'YES') IS_UNIQUE, GROUP_CONCAT(CONCAT('`',COLUMN_NAME,'`') ORDER BY IF(INDEX_TYPE='BTREE',SEQ_IN_INDEX,0), COLUMN_NAME ) COLUMNS FROM information_schema.STATISTICS GROUP BY TABLE_SCHEMA,TABLE_NAME,INDEX_NAME,INDEX_TYPE,NON_UNIQUE ) ndx1 INNER JOIN ( SELECT TABLE_SCHEMA,TABLE_NAME,INDEX_NAME,INDEX_TYPE, IF(NON_UNIQUE, 'NO', 'YES') IS_UNIQUE, GROUP_CONCAT( CONCAT('`',COLUMN_NAME,'`') ORDER BY IF( INDEX_TYPE = 'BTREE' , SEQ_IN_INDEX , 0) , COLUMN_NAME ) COLUMNS FROM information_schema.STATISTICS GROUP BY TABLE_SCHEMA,TABLE_NAME,INDEX_NAME,INDEX_TYPE,NON_UNIQUE ) ndx2 ON ndx1.TABLE_SCHEMA = ndx2.TABLE_SCHEMA AND ndx1.TABLE_NAME = ndx2.TABLE_NAME AND ndx1.INDEX_NAME != ndx2.INDEX_NAME AND ndx1.INDEX_TYPE = ndx2.INDEX_TYPE AND CASE WHEN ndx1.COLUMNS = ndx2.COLUMNS AND (ndx1.IS_UNIQUE = 'NO' OR ndx1.IS_UNIQUE = ndx2.IS_UNIQUE) THEN TRUE WHEN ndx1.INDEX_TYPE = 'BTREE' -- when BTREE AND INSTR(ndx2.COLUMNS, ndx1.COLUMNS) = 1 AND ndx1.IS_UNIQUE = 'NO' THEN TRUE ELSE FALSE END GROUP BY ndx1.TABLE_SCHEMA,ndx1.TABLE_NAME,REDUNDANT_INDEX_NAME ;
顯然,每個分組的列最少的索引需要被淘汰
根據選擇性查找未使用的索引。
在我的開發者時代,我沒有對未使用的索引做太多事情。我嘗試只創建與以下子句匹配的必要索引:
- 在哪裡
- 通過…分組
- 訂購方式
如果您必須通過搜尋未使用的索引來清理數據庫,請閱讀以下內容:
使用 Percona-Server 而不是 MySQL,因為 Percona-Server 有額外的 information_schema 表,用於記錄自 mysql 啟動以來的索引使用情況。
一個很古老的工具叫mysqlidxchk
監控伺服器參數(什麼應該是重要的參數)
- Innodb_buffer_pool_pages_dirty *100.0/ Innodb_buffer_pool_pages_total:需要刷新的 InnoDB 緩衝池的百分比(如果超過 5%,我會密切關注伺服器負載)
- (100.0 * (Delta( Innodb_buffer_pool_read_requests ) - Delta( Innodb_buffer_pool_reads ))) / Delta( Innodb_buffer_pool_read_requests : InnoDB 的讀取效率
- 100.0 * (1.0 - (三角洲($$ Key_reads $$) / 三角洲($$ Key_read_requests $$)) : MyISAM 的讀取效率(應該在 90% 以上,更不用說使用 memcached 記憶體數據或切換到 InnoDB)
這只是要監控的全域狀態值的一個範例。請閱讀有關伺服器狀態變數的 MySQL 文件。
執行 MySQL Server 性能調整腳本
最直接的腳本是 mysqltuner.pl 得到它並執行它
# wget mysqtuner.pl # perl mysqltuner.pl
慢日誌
慢日誌在低流量環境中非常有用。不幸的是,我看到了太多的以下情況
- 大量數據庫連接
- 執行相同類型查詢的所有連接
- 在一個連接中查詢阻塞了數十個需要相同表或行的其他連接(即使使用 InnoDB,因為執行 UPDATE 時與聚集索引相關的死鎖問題)
在這種情況下,當大量需要公用表的查詢時,我的查詢會以極快的速度獨立工作。
恕我直言,慢查詢日誌實際上對您沒有好處*,因為它記錄*了被視為慢的已完成查詢。您真正想要做的是在長時間執行的過程中擷取長時間執行的查詢。因此,我建議使用pt-query-digest來匯集程序列表(或 tmpdump)以用於執行 amok 的查詢。我在 2011 年 12 月寫了一篇關於如何編寫 crontab 作業腳本的文章,該作業使用mk-query-digest每 20 分鐘輪詢一次程序列表(可以在其中插入 pt-query-digest)。