ついさっきWordPressでリビジョンを無効化する件について書きました。
WordPressのリビジョン管理を無効化して不要なデータを削除 | 曖昧/旬.
そして大量のリビジョン情報を削除しました。
そうなると気になるのがMySQLデータベースのフラグメント化です。
フラグメント化って何かというと、歯抜けです。ぴっちり並んでいれば効率がいいのに、間開けて並んじゃっているから効率が悪くなっている状態です。
データベースでフラグメント化がいつ発生するかというと、主に行の削除です。行の削除は例えるなら、びっしり書かれた大学ノートのある1行を横線引いてなかったコトにしているようなものです。物理的には行が残っているのです。削除がどんどん走ると横線だらけになって生きたデータはほとんど残っていないかもしれません。
データベースがそんな状態だと、せっかく要らないデータを消したのに、効率は大して変わっていないかもしれません。それを解消する方法はデータベースによって異なります。MySQLなら OPTIMIZE TABLE というコマンドがあります。こいつはデータの最適化をしてくれます。PostgreSQLだと VACUUM FULL ですね。例えるなら、新しいノートに順序良く書き写して古いノートを捨てる処理です。
さて、まずMySQLはどの程度フラグメント化しているのでしょう。とりあえず SHOW TABLE STATUS で見てみます。記事を格納したテーブルにクローズアップ。
mysql> SHOW TABLE STATUS LIKE 'wp_posts';
出力は長すぎるので省略。重要なところは Data_length がテーブルのデータサイズで、Data_free が歯抜けの総量、ついでに Index_length がインデックスのサイズですね。この辺りの数値が OPTIMIZE でどう変化するか。OPTIMIZE します。
mysql> OPTIMIZE TABLE wp_posts;
完了。うちはデータ1,000件ほどですが、ほぼ一瞬でした。よっぽどじゃないと待つことにはならないでしょうね。そして数値を確認。Data_free が0になって、減った分 Data_length が小さくなっているはずです。ついでに Index_length も多少短くなっているはず。
というわけで、せっかくリビジョンの件から発展させているので、リビジョンデータを削除する前からの変化を見てみましょう。
タイミング | Data_length | Data_free | Index_length |
---|---|---|---|
削除前 | 4466256 | 2704 | 258048 |
削除後 | 4466256 | 2264980 | 261120 |
OPTIMIZE TABLE後 | 2200740 | 0 | 208896 |
分かりやすいですね。データを削除すると歯抜けが発生して、最適化すると歯抜けがなくなってデータ長が短くなる。削除後のデータ長から歯抜け分を引くと2201276なので OPTIMIZE TABLE 後のデータ長とほぼ合います。若干ずれるのはテーブル構造の問題でしょう。
これで多少は効率化するでしょうか。ギリギリの運用ではないので差は出ないと思いますが、後でCPU使用率でも見てみるかな。アクセス数にもよるから一概に言えないんだけどね。
ちなみに OPTIMIZE TABLE する時はテーブル名をカンマで区切れば複数指定することができます。でも、ちょっと面倒。そんな人には wp-cli です。既にインストールしていたら、これを打つだけ。
$ wp db optimize
素晴らしい。しかし意図しているのかは分からないが、WordPressとは関係のないテーブルも OPTIMIZE してくれる。うちんとこは別にいいんだけど、OPTIMIZE 中はテーブルがロックされちゃうので余計なお世話なとこもありそう。
そして、この OPTIMIZE TABLE、あまり頻繁に実施する必要はないそうです。
可変長行の更新を頻繁にするとしても、特定のテーブルに対してだけ、この作業を週に一度、または月に一度以上する必要はありません。
情報源: MySQL :: MySQL 5.1 リファレンスマニュアル (オンラインヘルプ) :: 8.5.2.5 OPTIMIZE TABLE 構文.
まー、やっても悪くはならないだろうけど。