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のテンプレートを仕事で書く人は覚えておくべき基本の一つかもね。

もんのすごいタイムリーな記事でした(思わずコメントしてしまうくらいに)。
ほんと、どうもありがとうございますっ!!!
テンプレートレベルで下手な最適化を勧めるのはどんなものかと思いました。
それならmt-config.cgiでMaxResultsの値を穏当な値にすることを勧めるのがまず先だと思います。MaxResultsを10くらいに設定して許容可能なクエリー数に収まるのであれば問題ありませんよね。
(o)さん
>MaxResultsを10くらいに設定して許容可能なクエリー数に収まるのであれば問題ありませんよね。
う〜ん、Web屋さん的には検索結果が10件だと(20件でも多分)要求満たせないので。
昨日検索の実装をしていて、ほぼ終わってから改めてmt-search.cgiのソース(実際はApp/Search.pmのソースを)眺めてから、SQLのクエリーをログ保存して確認してみたというところです。あと、mt-search.cgiはあくまでも例です。
この話には続きがあるのですが、そのあたりはまたいずれ書きます。
>う〜ん、Web屋さん的には検索結果が10件だと(20件でも多分)要求満たせないので。
「検索結果セット全体」という意味では十分な大きさをサポートしなければならないのは当然ですが、「検索結果の表示インタフェースが一度に取り扱うデータ」という意味では10~20件程度というのはまず適切な値です(Googleで検索すれば分かるとおり)。Junnamaさんの言う「Web屋さん的な検索結果」とは何を指しているのでしょうか。
mt-search.cgiは素朴な実装ゆえにこの両者が一致しているだけです。だから表示インタフェースを軽量にしたければ検索結果セットをトリミングする必要があります。ですからMaxResultsを小さく設定する、と。
普通に実装するならmt-plusのような設計を選択しますね。つまり、スケーラブルなバックエンドと軽量にレンダリングできるフロントエンドの組み合わせ、です。