はじめに
MySQLテーブルに適切なインデックスを作成することにより、SELECTクエリのパフォーマンスを大幅に向上させることができます。 しかし、インデックスをテーブルに追加するコストが高いですし、テーブルのサイズによっては完了するまでにかなりの時間がかかる場合があります。インデックスを追加している間にインデックス自体の作成にリソースが使われているためDBのパフォーマンスが低下する可能性があります。 この投稿では、通常のワークロードが影響を受けないようにMySQLインデックス作成プロセスを最適化するアプローチについて説明します。記事のソースはこちらです。
インデックスのローリング作成
MySQLマスター/スレーブのセットがある場合、一度に一つのノードでローリング方式でインデックスを作成できます。 マスターのパフォーマンスに影響を与えないように、スレーブノードでのみインデックスを作成する必要があります。スレーブ上でインデックスの作成が完了すると、現在のマスターを降格し、新しいマスターとしてスレーブを昇格させます。 この時点で、インデックスの構築は元のマスターノード(現在はスレーブ)で続行されます。 フェールオーバーのためにデータベースへの接続が失われる間、短い期間(数十秒)がありますが、これはアプリケーションレベルでリトライを行うことで乗り越えられます。
ローリング作成の利点
インデックスのローリング作成のパフォーマンスの利点を理解するために、小さな実験を行いました。
次のテストでは、Sysbenchを使用して作成されたMySQLデータセットを使用しました。各データベースには、5000万行の三つのテーブルがありました。 バランスの取れたワークロード(50%の読み取りと50%の書き込み)を10分間実行する30のクライアントでMySQLマスターに負荷をかけて、同時に、次のシナリオでいずれかのテーブルに単純なセカンダリインデックスを構築しました:
- マスターでインデックスを作成する
- スレーブでインデックスを作成する
MySQLコンフィグ
MySQLインスタンスタイプ | EC2インスタンス m4.large with 8GB RAM |
デプロイメントタイプ | 2 Node Master-Slave Set 準同期レプリケーション |
MySQL Version | 5.7.25 |
試験結果
シナリオ | クエリ/秒 | 95パーセンタイルレイテンシー |
---|---|---|
マスターでのインデックス作成 | 453.63 | 670 ms |
ローリング作成 | 790.03 | 390 ms |
結論
マスターでのインデックス作成時のスループットがローリング作成時のスループットの60%しか出せませんでした。 クエリの95パーセンタイルレイテンシも、マスターでインデックス作成が行われたときに1.8倍高くなりました。
ローリング作成の自動化
ScaleGridは、MySQLインデックスのローリング作成の自動化に役に立ちます。UIも結構シンプルです。
上記のUIでは、データベース名とテーブル名を選択し、「インデックスの追加」をテーブル変更操作として選択できます。 次に、カラム名とインデックス名を指定すると、テーブル変更コマンドが生成されて表示されます。 [作成]をクリックすると、インデックスの作成はローリング方式で一度に1つのノードで行われます。
さらに、ScaleGridは、新しいカラムをローリング方式でテーブルに追加するなど、他の単純なテーブル変更操作もできます。