MTからデータベースへのクエリの発行回数を減らす (mt-search.cgiを例にとって)。
公開日 : 2007-09-25 01:23:07
SQLを意識せずにプログラミングできるのが僕がMTを好きな理由の一つであるけれども。
たまにはMTがどんなクエリを発行しているか見てみよう。
MySQLを起動、mt-search.cgiで検索して、MySQLのログを覗いてみる。行数は起動の際のログも含めた行数。
MySQLのログはMAMPの場合、/Applications/MAMP/bin/startMysql.sh に
--log=/Applications/MAMP/logs/mysql_log
とか追加すればログが保存されるようになる。
MT4デフォルトの「検索結果」テンプレートだと、
- 1件がマッチするキーワードでの検索: ログは122行(41クエリ)。
- 100件がマッチするキーワードでの検索:ログは1310行!(437クエリ!)。←何ということでしょう!?
CGIの起動がネックだとか、LIKE検索せずにPerlのマッチングだけでやているから遅いとか色々と各所で指摘はされているけれども、SQLのクエリーの数だけでも相当なものだ(特にヒット数が多い場合)。
次に、「検索結果」テンプレートの「ブログ記事の概要」モジュールのところを削除して、
<p><a href="<MTEntryPermalink>"><MTEntryTitle></a></p>
のようにタイトル部分がリンクするようなシンプルな検索結果が表示されるようにする。
- 1件がマッチするキーワードでの検索: ログは98行(33クエリ)。
- 100件がマッチするキーワードでの検索:ログは98行(33クエリ!)。←何ということでしょう!?
これだけ差があるとCGIの起動とかPerlのマッチング云々以前に、DBが高速でない場合には明らかなレスポンスの差につながると思われる。さて、この差はなんだろう?
アクセスするテーブルが多い程クエリは増える。
犯人はコイツ↓
MTのデータベースの構造を見てみた人なら知っていると思うけど、「コメント」や「トラックバック」、「カテゴリ」といった情報は mt_entryテーブルとは別のテーブルになっている。特に「トラックバック」や「カテゴリ」はそれぞれ mt_trackback & mt_tbping, mt_placement & mt_category というように2つのテーブルにアクセスしないといけない。あと「タグ」もそう。
よって、デフォルトの「検索結果」テンプレートにおいてマッチ数が多いときにログ(クエリ) を膨らませているのは、この「トラックバック」と「コメント」である。
もちろん、検索に限らず例えばダイナミックパブリッシングにおける一覧ページ系においてはできるだけ複数のテーブルを参照しないようなテンプレートの作り方をすれば少なくともDBへ発行するクエリの数は減る。エントリー(ウェブページ)であれば、概要欄やキーワード欄、追記欄等は同一のテーブル内。だから、記事のメタ情報について「タグ」や「カテゴリー」を利用しているけど、エントリーの概要欄やキーワード欄、追記欄を利用していない、という場合はこれらのフィールドをできるだけ活用して他のテーブルにクエリを投げる回数を減らしてやるとちょっとだけ幸せになれるかも。
もちろん、テンプレートのメンテナンス性とか管理画面のユーザビリティ的にとかそのあたりとトレードオフになる場合もあるけれど、MTのテンプレートを仕事で書く人は覚えておくべき基本の一つかもね。