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


8

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

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

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

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

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

ありがとう

回答:


9

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%を構成する冗長データがあることに気付いたとします。確かに、そのディスク領域を元に戻すのは素晴らしいことです。

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


data_freeは役に立たないことに同意します。フラグメンテーションを計算するためのひどいメトリックであるテーブルスペースの「空きエクステント」内のスペースのみをカウントします。使用しinnodb_file_per_tableていない場合は、共有テーブルスペースのすべてのテーブルに同じ値が表示されると思います。
jeremycole 2014年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.