web-dev-qa-db-ja.com

MySQLでInnoDBテーブルを最適化する方法

MySQLで断片化されたテーブルのみを最適化する方法を調査して、レビューしました テーブルの最適化に関するこの投稿 。基本的には、data_free > 0を含むすべてのテーブルのinformation_schemaデータベースに対してクエリを実行し、それらのテーブルのみをOPTIMIZEにするSQLステートメントを作成します。このクエリを実行すると、最適化のために148のテーブルが特定されました。識別されたすべてのテーブルはInnoDBテーブルです。結果の最適化SQLスクリプトを実行した後、元のスクリプトを再実行して断片化されたテーブルを特定しましたが、最初のパスでまったく同じテーブルが返されました。

InnoDBテーブルとOPTIMIZEコマンドに関して競合する投稿を見ました。 OPTIMIZEはInnoDBテーブルでは機能せず、ALTER TABLE table_name ENGINE=INNODBを実行する必要があると言う人もいます。他の人は、InnoDBテーブルに対して実行するときにOPTIMIZEが実際にALTER TABLEコマンドを呼び出すと言います。そのことを念頭に置いて、フラグメント化されていると識別されたInnoDBテーブル(ALTER TABLE)の1つに対してdata_free > 0コマンドを実行したところ、data_freeは後で変更されないことがわかりました。それでもまだ0を超えています。MySQLを再起動して確認したところ、同じ結果が見つかりました。

現在、MySQL 5.5.29を実行しているサーバーが複数あり、私はそれらすべてに対してクエリを実行して、DATA_FREE=0 or NULLのInnoDBテーブルを特定しましたが、何も返されませんでした。それらはすべてゼロより大きいです。

また、いくつかのOPTIMIZEテーブルに対してMyISAMコマンドを実行し、DATA_FREEがゼロよりも大きい場合は、後でゼロであることを確認しました。

誰かがこれについていくつかの光を当てることができますか? InnoDBテーブルから断片化を削除する適切な方法は何ですか?断片化されたInnoDBテーブルを特定する適切な方法は何ですか?

ありがとう

8
user3151788

この回答にinnodb_file_per_tableを使用していると仮定します。

「InnoDBフラグメンテーション」には複数の意味があります。

  1. .ibdファイルは断片化されており、非常に大きいのにデータセットは小さい
  2. インデックスページは断片化されており、ページが多すぎてデータをほとんど含めることができません。その場合、それらをマージできます。

検討してください この投稿 しばらく前に書きました:大きなテーブルから多くの行をパージした後、データファイルが断片化される方法を示します(つまり、ファイルシステムで非常に大きいです-これは既知の問題です)ファイルのサイズが小さくなることはありません)。しかも、インデックスは削除の終わりまでに断片化されていませんでした。これは、InnoDBが空になるとページが適切にマージされるためです。

実際、OPTIMIZEコマンドはInnoDBには適用されません。これは、テーブルを再構築することです(ALTERとまったく同じです)。これを見てください:

mysql [localhost] {msandbox} (test) > create table t(id int) engine=innodb;

mysql [localhost] {msandbox} (test) > optimize table t;
+--------+----------+----------+-------------------------------------------------------------------+
| Table  | Op       | Msg_type | Msg_text                                                          |
+--------+----------+----------+-------------------------------------------------------------------+
| test.t | optimize | note     | Table does not support optimize, doing recreate + analyze instead |
| test.t | optimize | status   | OK                                                                |
+--------+----------+----------+-------------------------------------------------------------------+

DATA_FREEについては、この変数を無視することをお勧めします。正直なところ、私は10年間InnoDBテーブルを使用してきましたが、この値が何かと非常に一貫していることを発見したことがありません。

そして今、本当の議論の時間です:あなたは正確に何を達成しようとしていますか?データベースが完全に古くならない限り、断片化が常に存在します。テーブルの行を追加、削除、更新するプロセスは自然です。

断片化はそれほど悪いことではありません。空き領域は新しいデータによって再利用される可能性があります。テーブルがそれほど大きくない場合は、すべてを忘れてください。非常に大きなテーブルの場合、テーブルを最適化することにより、ディスク容量を増やすことができます。しかし、自問してみてください。テーブルがどれだけ早く同じ断片化に到達するのでしょうか。 1時間?一日?一週間?これらすべてのケースでIMHOは、テーブルを最適化しても意味がありません。

それでも、大きなテーブルで大量のデータが消去され、返されることが期待されない場合は、私はそれを最適化することに全力を尽くしています。テーブルサイズの約30%を構成する冗長データがあることに気付いたとします。確かに、そのディスク領域を元に戻すのは素晴らしいことです。

結論:これらの問題は非常に大きなテーブルでのみ考慮してください。ディスク容量に問題がある場合のみ。

9
Shlomi Noach