Table optimizer

WordBench 東京が開催した黙々と何かを作る勉強会もくもく部
当日は大掃除したりなんだりで、リアルタイムには参加できなかったのですが、あまりに楽しそうだったので、夜中にこっそりビールを呑みながら、一人もくもく部をやってました。
で、1時間あまりで作ったプラグインがこれ。

http://dl.dropbox.com/u/110305/optimizer.php

wp-cron という WordPress で定期実行してくれる仕組みを使って定期的に全テーブルを optimize してくれるプラグインです。
地味に便利だと思いますよ。

一応、簡単な説明。
やってることは単純で "SHOW TABLES" を発行して、全テーブル名を取得し、その中から $wpdb->prefix でプリフィックスが WordPress で使用しているテーブルと一致するモノを "OPTIMIZE TABLE" してるだけです。
定期的に OPTIMIZE しなくても ANALYZE だけで充分だよ。という人は OPTIMIZE TABLE を ANALYZE TABLE に書き換えてやってください。

MySQL や一般的な RDBMS では、定期的に ANALYZE してやって、テーブルのキーの分布を分析・格納してやることで、DBアクセス時のパフォーマンスアップが見込めます。
動的生成の WordPress では、定期的に ANALYZE TABLE もしくは OPTIMIZE TABLE してやると幸せになれるでしょう。

define('OPTIMIZER_INTERVAL', 24 * 60);
define('OPTIMIZER_SCHEDULE_HANDLER', 'optimize_table');

class OptimizeTable {

	function optimize_table(){
		global $wpdb, $table_prefix;


		$tables = $wpdb->get_col('SHOW TABLES');
		$pattern = '/^'. preg_quote($wpdb->prefix) . '/i';
		foreach ( $tables as $table ) {
			if ( preg_match( $pattern, $table ) ) {
				$wpdb->query("OPTIMIZE TABLE $table");
			}
		}

		$time_interval = OPTIMIZER_INTERVAL;
		$this->schedule_single_event($time_interval);

	}

	// get wp-cron schedule
	function _get_schedule($schedule_procname = OPTIMIZER_SCHEDULE_HANDLER) {
		$schedule = array(
			'procname' => '' ,
			'enabled' => FALSE ,
			'time' => '' ,
		);

		$crons = _get_cron_array();
		if ( !empty($crons) ) {
			foreach ( $crons as $time => $tasks ) {
				foreach ( $tasks as $procname => $task ) {
					if ($procname === $schedule_procname) {
						$schedule['procname'] = $procname;
						$schedule['time'] = $time;
						$schedule['enabled'] = true;
						break;
					}
				}
				if ($schedule['enabled']) break;
			}
			unset($procname); unset($task);
			unset($time); unset ($tasks);
		}
		unset($crons);

		return ($schedule);
	}

	function schedule_single_event($time_interval = OPTIMIZER_INTERVAL) {
		return (wp_schedule_single_event(time() + $time_interval * 60, OPTIMIZER_SCHEDULE_HANDLER));
	}

	function schedule_enabled($schedule_procname = OPTIMIZER_SCHEDULE_HANDLER) {
		$schedule = $this->_get_schedule($schedule_procname);
		return ($schedule['enabled']);
	}
}

$optimizer = new OptimizeTable();
if ( !$optimizer->schedule_enabled() ) $optimizer->schedule_single_event(0);
add_action(OPTIMIZER_SCHEDULE_HANDLER, array(&$optimizer, 'optimize_table'));
unset($optimizer);

5 thoughts on “Table optimizer

  1. おで

    最適化は phpmyadmin 開くとたまにやって、オーバーヘッドを解消していたんですけど、
    もちろん開いたときだけで全然定期的ではなかったんです。

    アクセスとコメントがハンパない大手サイトではないので、
    1日はやっぱりみじかいですよね。。。でもそんなに負担かかってなさそうだから、とりあえずこのままでw

    返信
  2. おで

    了解です。
    1日間隔でも問題なければこのままでいいですよね。
    コア鯖の調子のせいもあるとおもうんですが、さっき見たらものすごく表示が早くなってました(笑)

    返信
    1. をかもと 投稿作成者

      OPTIMIZE TABLE ないし ANALYZE TABLE は定期的にやった方が良いです。
      データの増加量にもよりますが、DBにキー分布を正しく把握させておけば、適切なインデックスを使って検索してくれるので、かなり速くなります。
      # WordPress 程度のアプリであれば1日間隔は短かすぎですが 😛

      ちなみに OPTIMIZE TABLE って命令は phpMyAdmin で、テーブルを選択して「最適化」をやってもできます。

      返信
  3. おで

    ボス(‘◇’)ゞ
    さっそく入れてみました。

    デフォルトでは1日ごとに cron を回しているって理解でいいのかな。

    返信
    1. をかもと 投稿作成者

      おでさん、どもです。

      define('OPTIMIZER_INTERVAL', 24 * 60); って所で、間隔(分で指定)を決めてます。
      これを1週間間隔にしたければ、 define('OPTIMIZER_INTERVAL', 7 * 24 * 60); に書き換えてください。

      返信

コメントを残す

メールアドレスが公開されることはありません。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください