私たちのデータベースが稼働中の本番システムの主要なボトルネックになっていることに気付いた後、問題の根底に到達するための簡単なベンチマークを作成することにしました。
ベンチマーク: InnoDB テーブル内の同じ行を 3000 回インクリメントするのにかかる時間を測定しました。行はその主キーによってインデックス付けされ、更新される列はインデックスの一部ではありません。リモート マシンで実行されている 20 の同時クライアントを使用して、これらの 3000 の更新を実行します。それぞれのクライアントは、DB への個別の接続を備えています。
私がベンチマークしたさまざまなストレージ エンジン (InnoDB、MyISAM、および MEMORY) に、それぞれのプロファイルがある理由を知りたいと思っています。また、比較して InnoDB がそれほどうまくいかない理由も理解したいと思っています。
InnoDB (20 の同時クライアント): 各更新には 0.175 秒かかります。すべての更新は 6.68 秒後に完了します。
MyISAM (20 の同時クライアント): 各更新には 0.003 秒かかります。すべての更新は 0.85 秒後に行われます。
メモリ (20 の同時クライアント): 各更新には 0.0019 秒かかります。すべての更新は 0.80 秒後に行われます。
並行性がこの動作を引き起こしている可能性があると考えて、100 回の更新を順次実行する単一のクライアントのベンチマークも行いました。
InnoDB: 各更新には 0.0026 秒かかります。
MyISAM: 各更新には 0.0006 秒かかります。
MEMORY: 各更新には 0.0005 秒かかります。
実際のマシンは、ほとんどがデフォルト設定の Amazon RDS インスタンス ( http://aws.amazon.com/rds/ ) です。
答えは次のようになると思います: InnoDB は各更新後に fsync します (各更新は ACID 準拠のトランザクションであるため) が、MyISAM はトランザクションをサポートしていないためそうではありません。MyISAM はおそらくすべての更新をメモリ内で実行し、定期的にディスクにフラッシュします。これが、その速度が MEMORY ストレージ エンジンに近づく方法です。もしそうなら、トランザクションのサポートに InnoDB を使用する方法はありますが、(構成を介して) いくつかの制約を緩和して、耐久性を犠牲にして書き込みを高速化する方法はありますか?
また、クライアントの数が増えるにつれて InnoDB のパフォーマンスを向上させる方法について何か提案はありますか? 他のストレージ エンジンよりも明らかにスケーリングが悪いです。
アップデート
https://blogs.oracle.com/MySQL/entry/comparing_innodb_to_myisam_performanceを見つけました。これはまさに私が探していたものです。innodb-flush-log-at-trx-commit=2 を設定すると、電源障害またはサーバー クラッシュが発生した場合に備えて、ACID の制約を緩和できます (ディスクへのフラッシュは 1 秒に 1 回発生します)。これにより、MyISAM と同様の動作が得られますが、それでも InnoDB で利用可能なトランザクション機能を利用できます。
同じベンチマークを実行すると、書き込みパフォーマンスが 10 倍向上することがわかります。
InnoDB (20 の同時クライアント): 各更新には 0.017 秒かかります。すべての更新は 0.98 秒後に行われます。
他の提案はありますか?