MySQLクエリによって実行されるI / O操作を推定する方法


13

AmazonのRDSでは、100万回のI / Oリクエストごとに約0.10ドルを支払います。トラフィックが非常に少ないデータベースに対して、非常に多数(数十万)のI / O要求が発生していることに気付きました。これを見て、さらに調査を行ったところ、6,000のユーザーWebサイトに対して、1か月に8億のI / O要求が発生し、1か月あたり約80ドルの費用がかかるという質問が見つかりました。

したがって、MySQLクエリが生成するI / O操作の数と、それらを最適化/最小化する方法を事前に知りたいです。クエリが実行するI / O操作の数を見積もる方法と、それらをできるだけ低く保つために従うことができる一般的な規則はありますか?

回答:


2

Raymond Nijlandによる質問に対するコメントから生成されたコミュニティWikiの回答

を使用しEXPLAINます。これにより、クエリにディスクIOが必要かどうかを確認できます。列で余分な「一時的使用」または「一時的使用」を避ける必要があります。filesortの使用(filesortは誤解を招く名前です。結果セットがメモリに収まる場合、クイックソートはメモリで実行されます)。

これは、サブクエリ/ユニオン/オーダーby /グループby /が原因である可能性が最も高くなります。結果が大きく、MyISAMディスクベースの一時テーブルが作成され、結果をソートする必要がある場合は、結果をソートしています。クイックソートアルゴリズムによるIO読み取りおよびIO書き込みに基づいて設定されます。

MySQLの内部の一時表の使用 MySQLはディスクベースMyISAMテーブルを作成する必要がある場合、あなたは読むことができます。たぶんavg_row_length * rows(explainからのrows値はInnoDBエンジンでは正確ではないことに注意してください)を使用して、結果がヒープに収まるかどうかをチェックできます。SHOW TABLE STATUS構文を参照してください。

一般に、I / O要求を回避するにはInnoDBまたはMyISAMの方が適していますか?

InnoDBはテーブルデータとインデックスデータをバッファリングしますが、MyISAMはインデックスキーのみをバッファリングします。Explain列エクストラが「インデックスの使用」と言っていない場合、テーブルデータへのI / Oが必要です。

両方がインデックスを使用している場合:InnoDBでは、バッファーがホットな場合、メモリーからデータをロードできます。インデックスをディスクから取得する必要がある場合、選択、挿入、および更新に必要なIO読み取りを計算するために使用できる数式があります。クエリパフォーマンスの推定から:

小さいテーブルの場合、通常、1回のディスクシークで行を見つけることができます(おそらくインデックスがキャッシュされているためです)。より大きなテーブルの場合、Bツリーインデックスを使用して、行を見つけるためにこれだけのシークが必要であると推定できます。

log(rows) / log(index_block_length / 3 * 2 / (index_length + data_pointer_length)) + 1

InnoDBインデックスは、PRIMARY / UNIQUEキーからKEYインデックスにデータを保存するため、より大きくなります。これはより高速で、必要なIOシークはさらに少なくなりますが、InnoDBデータまたはインデックスを圧縮できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.