web-dev-qa-db-ja.com

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

したがって、サーバーを検査するための順序と、パフォーマンスを改善するために監視/分析する必要がある正確なものは何でしょうか。

3
Abdul Manaf

重複するインデックスの検索

2012年1月に戻って、 @gbnは、Ronald Bradfordのブログ からの2つのビューを提示した重複インデックスに関する質問に回答します。2つのビューを1つのクエリに結合して、次のように重複インデックスを提示しました。 :

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
;

明らかに、グループ化ごとに列が最も少ないインデックスを削除する必要があります

選択度に基づいて未使用のインデックスを見つけます。

開発者の日は、未使用のインデックスをあまり使っていません。私は、次の節に一致する必要なインデックスのみを作成しようとします。

  • どこ
  • GROUP BY
  • 注文する

未使用のインデックスを探し出してデータベースをクリーンアップする必要がある場合は、以下をお読みください。

サーバーパラメータを監視する(重要なパラメータを指定する)

これは、監視するグローバルステータス値のサンプルにすぎません。 サーバーステータス変数のMySQLドキュメント を参照してください。

MySQLサーバーのパフォーマンス調整スクリプトを実行する

最も簡単なスクリプトはmysqltuner.plです。取得して実行するだけです。

# wget mysqtuner.pl
# Perl mysqltuner.pl

遅いログ

遅いログは、トラフィックの少ない環境で非常に役立ちます。残念ながら、私は次のことが多すぎます

このシナリオを考えると、クエリが急増してスタンドアロンで動作するクエリがあり、クエリの殺到が共通のテーブルを必要とするときに停止します。

それが遅いと見なされる完了したクエリを記録するので、遅いクエリのログは実際にあなたによくないので私見です。本当にやりたいことは、実行時間の長いクエリをキャッチすることです。したがって、 pt-query-digest を使用して、amokを実行しているクエリのプロセスリスト(またはtmpdump)をプールすることをお勧めします。 2011年12月に、プロセスリストをポーリングするcrontabジョブをスクリプト化する方法に関する投稿を書きましたmk-query-digest を使用して20分ごとに(pt-query-digestをその場所に挿入できます)。

6
RolandoMySQLDBA