singleページでのコメントの表示数について、
ディスカッション設定によりコメントを複数ページに分割表示できるものの、singleページを表示するタイミングで取得するコメントは常にその記事に関するコメントすべてとなる。つまりコメントを5件づつ表示する場合でも、その投稿についてコメントが100件あれば100件を取得している。
あるサイトのサーバー負荷が異様に重くて調べたところ、特定の記事についてコメントが10000件以上ついているためと分かった。この10000件とは決してスパムではなく、singleページがFLASHゲームで遊ぶ構成になっているため人気ゲームにコメントがたくさんついてしまったのだ。コメントは最新の50件を5件づつ分割表示している。必要なコメントは50件なので、できれば古くなったコメントを削除してしまいたかった。しかしサイト運営者からは過去のコメントを削除しないようにと要求されている。
そうこうしているうちに、問題となるslow queryが浮かび上がった。
SELECT wp_comments.* FROM wp_comments WHERE comment_post_ID = '99' AND comment_approved = '1' ORDER BY comment_date_gm
このSQL文はwp-includes/comment-template.phpのcomments_template()という関数にあった。singleページを表示するさいにグローバル変数の$commentsにコメント配列をセットしている部分である。
ここにLIMITを追加すればよいのだろうがコアコードは修正できない。フォーラムで質問したところ、query フックでlimit句を追加するアドバイスをいただいた。しかし、コメント取得のSQL文は3とおりがあり並び順が固定の場合もあるため、どうも思ったとおりにいかない。そうこうしているうちに、コメントの取得に件数が制限できないのはコメント階層を考慮してのことだと気付いた。単純にLIMITを付けるだけではダメなのだ。
今回はコメント階層を使っていないということもあり、comments_template()をfunction.phpにリネームコピーしてカスタマイズすることで対処した。 ここのSQL文のORDERをDESCにして、LIMITを追加。さらにsingle.phpからcomments_template()を呼んでいる部分を、新しい関数名に変更した。
問題のsingleページはなんとか軽くなったように思う。
こんな対応でよいのかな?10000件もコメントがつくとは想定外だ。