Scribble at 2019-06-18 14:50:55 Last modified: 2022-09-29 10:51:58

ZAP

WordPress をカスタマイズしている某サイトでページの表示が異様に重いという件は、データベースのログを二つもらっていただけだったが、追加で幾つか情報をもらった。45 MB もあるログは、同じ処理の繰り返しが多いのでクエリの処理がおかしいのかと思ったが、1時間の間に処理したクエリということで、1つのページを表示するために 45 MB ものログを必要とするクエリが繰り返されたわけではないということが分かった。そして、そもそも該当するサイトを表示すると、トップページやカテゴリーのページは3秒以内に表示が完了するため、騒ぐほどのものではないと分かった。ただし、個別記事の表示はそれなりに所要時間がかかるようなので、テンプレートももらってあるから、エントリーに関連するコードを眺めることにした。データベースのログだけでは、仮に何か無駄な繰り返しが起きていたとしても、それが PHP や WordPress のテンプレート・タグとしてどういう書き方で起きているのかが分からないからだ。

そして、テンプレートを見ると、フッタで使っているユーザ定義関数の幾つかに無駄な処理が見つかった。それは、表示する記事に関連するタグの一覧を表示するという処理だ。おおまかな処理の流れとしては、A() という前処理の関数でデータを取得し、B() という関数でタグごとに一定の方針でウェイトをかけてからウェイトごとに並べ直して、ユーザ定義関数の引数として指定された個数だけタグをリンク付きでページに出力するということになっている。しかし、タグを並べるのが目的であるはずが、この A() という前処理ではタグごとに取得した個々の記事のタイトルや publish された日付まで取得して、わざわざ別の配列に格納して return している。前処理として書かれている関数なので、そういう処理が後から必要なのかと思ったが、タグを並べるだけなのに、なんで記事のタイトルが必要なのか。

そして、A() からの戻り値である配列を引数とする B() では、タグごとに重複している記事を削除したり、何の順番でか sort() で並べ直したりしているのだが、重複するデータを削除するのは前処理の関数でやっておくべきことだろうし、配列のデータを並べ直すのは、並べ方に特別な意味があるときだけでいい。そして、並べ直したデータに基づいて殆ど同じデータを WP_Query で呼び出しなおしているため、無駄なクエリが発生しているのだろう。40個のタグを並べるページだと、おおよそ50回ていどクエリを投げていることになるようだ。こんなのは、必要なタグの ID を配列にして1回のクエリで処理するべきことである。

  1. もっと新しいノート <<
  2. >> もっと古いノート

冒頭に戻る


※ 以下の SNS 共有ボタンは JavaScript を使っておらず、ボタンを押すまでは SNS サイトと全く通信しません。

Twitter Facebook