Mysql

如何提高 MySQL 伺服器性能..?

  • October 22, 2020

作為 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
;

顯然,每個分組的列最少的索引需要被淘汰

根據選擇性查找未使用的索引。

在我的開發者時代,我沒有對未使用的索引做太多事情。我嘗試只創建與以下子句匹配的必要索引:

  • 在哪裡
  • 通過…分組
  • 訂購方式

如果您必須通過搜尋未使用的索引來清理數據庫,請閱讀以下內容:

監控伺服器參數(什麼應該是重要的參數)

這只是要監控的全域狀態值的一個範例。請閱讀有關伺服器狀態變數的 MySQL 文件

執行 MySQL Server 性能調整腳本

最直接的腳本是 mysqltuner.pl 得到它並執行它

# wget mysqtuner.pl
# perl mysqltuner.pl

慢日誌

慢日誌在低流量環境中非常有用。不幸的是,我看到了太多的以下情況

在這種情況下,當大量需要公用表的查詢時,我的查詢會以極快的速度獨立工作。

恕我直言,慢查詢日誌實際上對您沒有好處*,因為它記錄*了被視為慢的已完成查詢。您真正想要做的是在長時間執行的過程中擷取長時間執行的查詢。因此,我建議使用pt-query-digest來匯集​​程序列表(或 tmpdump)以用於執行 amok 的查詢。我在 2011 年 12 月寫了一篇關於如何編寫 crontab 作業腳本的文章,該作業使用mk-query-digest每 20 分鐘輪詢一次程序列表(可以在其中插入 pt-query-digest)。

引用自:https://dba.stackexchange.com/questions/18975