改善施策については、第一に「根本的な解消」を考えましょう。必須な処理である場合、第二に、バックグラウンド処理の変更や部分キャッシュの適用を、最終的には、ページキャッシュの利用を検討します。最初からページキャッシュに頼ってしまうと、ボトルネックが放置されたままになるかもしれません。またキャッシュが切れた時点で、処理が追い付かなくなる可能性もあるため、安易に用いるべきではありません。
まずは、SQLのボトルネック改善方法を説明します。
最初に、データベースの設定が適切な値になっているかを確認しましょう。設定が適正になっていない場合、ディスクアクセスが増えることになり、パフォーマンスが劣化します。調整項目と適正値については、連載の第3回「CentOS 7の標準環境だけですぐできる、WordPress『5.4倍高速化』テクニック 前編」にて解説しているので、あらためて確認してください。
また、データベース自体が必要以上に肥大化していないか併せて確認します。
データ量については、「/var/lib/mysql」以下にあるデータベースごとのディレクトリ内に存在する各テーブルのデータファイルの中に、極端に大きなテーブルがないか確認します。「posts」テーブルは、コンテンツのデータが入るテーブルのため、サイズが大きくなりがちです。一般的な企業サイトの場合、100MB以内、メディアなど更新頻度が高いサイトの場合、2GB以内であれば一般的といえるでしょう。
ls -lh | grep \.ibd$ -rw-rw---- 1 mysql mysql 128K 10月 2 2015 wp_commentmeta.ibd -rw-rw---- 1 mysql mysql 176K 10月 2 2015 wp_comments.ibd -rw-rw---- 1 mysql mysql 112K 10月 2 2015 wp_links.ibd -rw-rw---- 1 mysql mysql 10M 2月 28 10:00 wp_options.ibd -rw-rw---- 1 mysql mysql 10M 2月 25 17:57 wp_postmeta.ibd -rw-rw---- 1 mysql mysql 36M 2月 27 00:35 wp_posts.ibd -rw-rw---- 1 mysql mysql 224K 2月 28 09:59 wp_redirection_404.ibd -rw-rw---- 1 mysql mysql 128K 8月 2 2018 wp_redirection_groups.ibd -rw-rw---- 1 mysql mysql 176K 2月 28 00:16 wp_redirection_items.ibd -rw-rw---- 1 mysql mysql 176K 2月 28 00:16 wp_redirection_logs.ibd -rw-rw---- 1 mysql mysql 160K 6月 30 2017 wp_site_cache.ibd -rw-rw---- 1 mysql mysql 96K 3月 17 2016 wp_sitemanager_device.ibd -rw-rw---- 1 mysql mysql 96K 3月 17 2016 wp_sitemanager_device_group.ibd -rw-rw---- 1 mysql mysql 112K 3月 17 2016 wp_sitemanager_device_relation.ibd -rw-rw---- 1 mysql mysql 112K 2月 20 19:40 wp_term_relationships.ibd -rw-rw---- 1 mysql mysql 128K 2月 20 19:43 wp_term_taxonomy.ibd -rw-rw---- 1 mysql mysql 128K 12月 24 2015 wp_termmeta.ibd -rw-rw---- 1 mysql mysql 128K 2月 19 20:55 wp_terms.ibd -rw-rw---- 1 mysql mysql 176K 2月 25 16:36 wp_usermeta.ibd -rw-rw---- 1 mysql mysql 144K 2月 20 2017 wp_users.ibd
各テーブルのレコード数は、以下のSQLで確認できます。
SELECT table_name, table_rows FROM information_schema.TABLES WHERE table_schema = '(データベース名)';
「posts」「postmeta」および「term_relationships」テーブルのレコード数は、作成されている投稿、固定ページ、メディアなどの総数に比例しているか、「comments」「commentmeta」テーブルは、コメントの総数に比例しているかを確認します。それ以外のテーブルは、1万レコードに達することはないので、それをしきい値として超えるような数値が出ていないか確認します。
MariaDB [(none)]> SELECT table_name, table_rows FROM information_schema.TABLES WHERE table_schema = 'wordpressdb'; +--------------------------------+------------+ | table_name | table_rows | +--------------------------------+------------+ | wp_commentmeta | 0 | | wp_comments | 0 | | wp_links | 0 | | wp_options | 184 | | wp_postmeta | 5775 | | wp_posts | 2925 | | wp_redirection_404 | 544 | | wp_redirection_groups | 2 | | wp_redirection_items | 0 | | wp_redirection_logs | 15 | | wp_site_cache | 0 | | wp_sitemanager_device | 9 | | wp_sitemanager_device_group | 2 | | wp_sitemanager_device_relation | 9 | | wp_term_relationships | 235 | | wp_term_taxonomy | 29 | | wp_termmeta | 0 | | wp_terms | 25 | | wp_usermeta | 411 | | wp_users | 18 | +--------------------------------+------------+
データベース自体が必要以上に肥大していないか確認するには、さまざまな機能に注意が必要です。
記事編集時に途中経過を自動保存し、復元も可能なWordPressのリビジョン機能は、編集履歴を追うことができて便利である半面、リビジョンが1つのレコードになるため、上限値の制限を設定しておかないと、postsテーブルが肥大化する原因になります。Transient APIは部分キャッシュとして有効である半面、データの保存先がoptionsテーブルになるため、安易に利用し過ぎると、WordPress起動時の設定読み込みに影響を及ぼしてしまいます。
カスタムフィールドを作れる「Advanced Custom Fields」プラグインは、便利である半面、postmetaテーブルのレコード数が多くなりがちです。また、アクセス数やクリック数、ランキングなどをデータベースにログ記録をするプラグインもデータ量が大きくなりがちなので、保存期限を設けるなど対策する必要があります。
次に、SQL自体の改善が可能か検討します。データベースのインデックスが有効に利用されているか、ファイルソートや一時テーブルの利用がないかなど、「EXPLAIN」構文を使って確認します。「WHERE」句や「ORDER BY」句を簡素化しても得られる結果に大きな差が発生しない場合、これらの条件自体を変更してクエリの高速化を図ることを検討すべきです。
他にも、SQLでは厳密な抽出やソートは行わず取得結果をPHPで処理した方が速いケースや、サブクエリが使われている状態でサブクエリを別のSQLとして分割し、2つのSQLとした方が結果として速くなるケースなどもあります。
アクション、フィルターには、通常複数のフックポイント(以下、フック)が登録されています。これらのうち、ボトルネックとなっているものを割り出すには、登録されているフックの半数を解除します。これにより、パフォーマンスが改善するのであれば、解除したフックにボトルネックが存在し、改善されないのであれば、解除しなかった残りのフックにボトルネックが存在することになります。これを繰り返し行い、ボトルネックを含むフックを特定し対処していきます。
フックにおけるボトルネックの種類はさまざまであり、一概に対処法はありません。しかし、総じて多いケースとして、下記2点が挙げられます。
外部のHTTPリクエストについては、バッチ処理として定期的にデータを取得しておき、処理時に、「取得後のデータを利用して解消する」もしくは「Transient APIを用いて頻度を低減する」のが有効です。
SQLの問題は、前述のSQLのボトルネック改善方法にて対処します。これらの改善を積み重ねることによって、3秒かかっていた処理が0.5秒未満まで改善したこともあります。地道な作業ではありますが、根気強く改善に取り組んでみてください。
今回は、WordPressサイトに対する、ボトルネックの見つけ方と改善方法について解説しました。
本連載は、今回で完結しますが、また別の連載で皆さんとお会いできることを楽しみにしております。
プライム・ストラテジー 取締役CTO(最高技術責任者)
プライム・ストラテジーにデザイナーとして入社、プログラマーへの転向を経て、現在はCTOとして技術研修や自動化施策の推進を行っている。多数のWordPress公式ディレクトリ掲載プラグインの開発やフォーラムなどのコミュニティー活動、『一歩先にいくWordPressのカスタマイズがわかる本』(翔泳社)『WordPress 3.x (速習デザイン)』(技術評論社)の執筆にも携わる。
Copyright © ITmedia, Inc. All Rights Reserved.