web-dev-qa-db-ja.com

MySQL InnoDBのテーブルのスケジュールされた最適化

MySQL InnoDBデータベースのテーブルの自動最適化をスケジュールする最良の方法は何ですか?たとえばイベントを使用できますか?最近、クエリの実行時に、実際にデータベースで最大のテーブルの1つで頻繁に更新されるテーブルの1つに大きなパフォーマンスの問題が発生しました。テーブルでOPTIMIZEを実行すると、問題が解決しました。

5
Shahid

OPTIMIZE TABLEは、テーブル(mydb.mytable)の内部で次の手順を実行します

_CREATE TABLE mydb.mytablenew LIKE mydb.mytable;
INSERT INTO mydb.mytablenew SELECT * FROM mydb.mytable;
ALTER TABLE mydb.mytable RENAME mydb.mytablezap;
ALTER TABLE mydb.mytablenew RENAME mydb.mytable;
DROP TABLE mydb.mytablezap;
_

DDLが関与しているため、操作中にクエリがパフォーマンスに大きな影響を与える回避策はありません。さらに、最適化を実行しないことも同様に悪いことです。

MySQL Master/Master(別名Circular)レプリケーションをセットアップする必要があります

次にこれを試すことができます:

サーバーM1とM2およびDB VIP M1を指す

M2で、次を実行します

_STOP SLAVE;
SET sql_log_bin = 0;
Perform OPTIMIZE TABLE or ALTER TABLE ... ENGINE=InnoDB on all InnoDB tables
START SLAVE;
Wait for replication to catch (Seconds_Behind_Master = 0)
_

_SET sql_log_bin = 0_は、DDLコマンドがマスター上で複製されるのを防ぎます。

これらの手順が完了したら、スレーブをマスターに昇格し、マスターをスレーブに降格します(DB VIPをM1からM2に移動するだけで実行できます)。このメンテナンスを毎日実行して、マスタープロモーションとスレーブデモーションを除いて、制作には影響がありません。

スクリプトを作成して、次のようにM2で実行できます。

_echo "SET sql_log_bin = 0;" > InnoDBCompression.sql
echo "STOP SLAVE;" >> InnoDBCompression.sql
mysql -u... -p... -AN -e"SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' ENGINE=InnoDB;') InnoDBCompressionSQL FROM information_schema.tables WHERE engine='InnoDB' ORDER BY (data_length+index_length)" >> InnoDBCompression.sql
echo "START SLAVE;" >> InnoDBCompression.sql
mysql -u... -p... -A < InnoDBCompression.sql
_

ここから、Seconds_Behind_MasterがM2で0になるのを待ってから、DBVIPをM1からM2に移動します。最適化したいテーブルの具体的な名前がわかっている場合は、クエリを調整してそれらのテーブルのみをフェッチできます。

試してみる !!!

警告

ここに公平な警告があります: innodb_file_per_tableの分散が解除されている場合、_OPTIMIZE TABLE_または_ALTER TABLE ... ENGINE=InnoDB;_を実行するたびに、ibdata1ファイルが大きくなります。 InnoDBインフラストラクチャをクリーンアップする必要があります ibdata1が制御不能にならないようにします。

5
RolandoMySQLDBA

イベントを使用して定期的に最適化を実行することもできますが、そのような改善を経験した場合、他の場所を調べる必要があるかもしれません。

Innodbの最適化は、alter table engine = innodbを実行して再構築し、多くの行を削除した結果である空のスペースを再利用するだけです。実際に使用されていないデータの推定量は、show table statusのdata_lengthとdata_freeの数値を比較することで確認できます。

最適化を実行した後、オペレーティングシステムは全体を読み取るだけなので、ディスクキャッシュにできる限り多くのテーブルを持っています。これにより、アクセス頻度の低いページがキャッシュから削除されるまで、短期的に改善されます。

完全な世界では、innodb_buffer_pool_sizeを十分に大きく設定して、すべてのinnodbテーブルをメモリに保持できるようにします。もちろん、予算や十分に大きいデータセットのために、これが常に可能であるとは限りません。同時に、これがinnodbテーブルのみの専用DBサーバーである場合は、バッファープールをシステムメモリの70〜80%に設定し、残りをOSオーバーヘッドとディスクキャッシュに残します。

編集

適切なハードウェアを確保するのと同じ要領で、できるだけ高速なディスクを入手してください。 FusionなどのPCI-E SSDベースのカードIOは今日できる最高の方法です。それを買う余裕はありませんか?マルチスピンドルを入手してくださいSAS RAIDディスクアレイ。

0
atxdba