「WordPressで学ぶPHP(3)関数編」を発売しました。
本書は「WordPressで学ぶPHP(1)変数・制御構造編」「WordPressで学ぶPHP(2)データ構造(配列・オブジェクト)編」の続編にあたり、PHP組み込みの関数や、独自の関数を作る方法などを解説します。
Kindle本で、定価400円です。
キャッシュの効果が出やすい/出にくいモジュール(その1)
小粋空間様で、以下のような記事がアップされていました。
藤本さんの記事に触発されて、Movable Type 4.2 RC2 のモジュールキャッシュを試してみました。
私もこの記事に触発されて(笑)、キャッシュの効果が出やすい/出にくいモジュールについての考察を書いてみました。
1.データベースアクセスが多いモジュールほど効果が高い
テンプレートを再構築する際には、大まかに言えば以下のような処理が行われます。
- 再構築に必要なデータをデータベースから読み込む
- テンプレートを解析して、テンプレートタグをデータに置き換える
- 再構築結果をファイルに保存する
データベースからデータを読み込む際には、多数のファイルにアクセスします。
特に、多くのデータにアクセスするほど、アクセスするファイルの数も多くなり、処理に時間がかかるようになります。
ハードディスクはCPUの処理速度に比べるとかなり遅いので、データベースアクセスが大量に発生すると、処理にかなりの時間がかかってしまいます。
つまり、データベースアクセスが多く発生するテンプレートモジュールは、再構築を遅くする原因になります。
先日の「複雑なキャッシュとその効果」では、「記事と同一カテゴリに属する記事一覧」をキャッシュしました。
この処理も、記事ごとにデータベースアクセスが大量に発生します。
しかも、記事が増えるほど、データベースアクセスの量が増えます。
そのため、キャッシュすることで大きな効果が得られました。
一方、テンプレートの解析はメモリ上で行われる処理です。
よほど巨大なテンプレートなら別ですが、一般的なテンプレートであれば、処理にはさほど時間はかかりません。
また、再構築結果をファイルに保存する処理では、1ページにつき保存対象のファイルは1つです。
そのため、これも処理にはさほど時間はかかりません。
2.カウント系のタグは処理に時間がかかる
テンプレートタグの中には、オブジェクトの個数を出力するものがいくつかあります。
その一例として、ブログ内の記事数を出力するMTBlogEntryCountタグがあります。
カウントの際には、カウント対象のすべてのデータにアクセスするので、ディスクアクセスが大量に発生します。
このため、カウント系のタグは、処理に時間がかかります。
実験として、記事300件のテストブログを対象に、カテゴリアーカイブのウィジェットを使って、以下の3つのケースでブログ記事アーカイブの再構築時間を測定してみました。
ケース | 内容 |
---|---|
ケース1 | カテゴリアーカイブのウィジェットをそのまま組み込む (カテゴリ一覧と、カテゴリごとの記事数を出力) |
ケース2 | カテゴリアーカイブのウィジェットから、MTCategoryCountタグを除いたものを組み込む (カテゴリ一覧のみを出力) |
ケース3 | カテゴリアーカイブのウィジェットを組み込まない |
すると、結果は以下のようになりました。
ケース | 再構築の所要時間 |
---|---|
ケース1 | 89秒 |
ケース2 | 54秒 |
ケース3 | 40秒 |
ケース1とケース2の違いは、MTCategoryCountタグがあるかどうかですが、これだけで再構築の所要時間が35秒伸びています。
カテゴリアーカイブのウィジェットを組み込まなかった場合(ケース3)は40秒で処理が済んでいますので、その処理にほぼ匹敵する時間を、記事数のカウントに費やしていることが分かります。
しかも、このウィジェットはすべてのブログ記事ページに組み込まれます。
したがって、キャッシュして再構築回数を1回に抑えれば、大きな効果が得られます。
3.キャッシュの効果が出にくいモジュール
ここまでで述べたように、キャッシュの効果が出やすいのは、データベースアクセスが大量に発生するモジュールです。
逆に言えば、データベースアクセスが少ないモジュールだと、キャッシュの効果は薄くなります。
また、モジュールによってはデータベースアクセスがまったくないものもありますが、それだとキャッシュの効果もほぼ0です。
例えば、MT4.2の標準テンプレートセットの「バナーヘッダー」というモジュールを考えてみます。
このモジュールは、各ページのヘッダー部分(ブログ名やブログの概要など)を出力するもので、以下のような内容になっています。
<div id="header"> <div id="header-inner"> <div id="header-content"> <mt:ignore><!-- Use h1 and h2 html tags on the main index of the blog as the title, use divs on all other pages where there are page titles. --></mt:ignore> <MTIf name="main_index"> <h1 id="header-name"><a href="<$MTBlogURL$>" accesskey="1"><$MTBlogName encode_html="1"$></a></h1> <h2 id="header-description"><$MTBlogDescription$></h2> <MTElse> <div id="header-name"><a href="<$MTBlogURL$>" accesskey="1"><$MTBlogName encode_html="1"$></a></div> <div id="header-description"><$MTBlogDescription$></div> </MTIf> </div> </div> </div>
このモジュールでは、ブログの情報を出力するために、MTBlog系のタグが入っています。
ただ、各ページを再構築する際には、MTBlog系のタグがあるかどうかに関係なく、ブログの情報をデータベースから読み込むようになっています。
したがって、上のモジュールをキャッシュするかどうかに関係なく、データベースアクセスの量は変化しない(はず)であり、キャッシュの効果は得られないと思われます。
実際、前述のケース3でこのモジュールをキャッシュしても、再構築の所要時間は40秒で、キャッシュしない場合と変化がありませんでした。
4.続きは後日
まだ他に書くべきことがありますが、記事が長くなってきましたので、続きは後日とさせていただきます。