今回は、WordPressデータベースのwp_optionsテーブルを見ていきます。WordPressとデータベースの総合パフォーマンスなら、このwp_optionsテーブルは見落とされがちです。特に大規模のウェブサイトでは、サードパーティ製プラグイン及びテーマにより残された自動読み込みデータのせいでクエリ時間が遅くなることがあります。本記事では、wp_optionsテーブルの確認、トラブルシューティング、整理などのやり方について説明します。

wp_optionsテーブルとは?

wp_optionsテーブルには、次のようなWordPressサイトの様々なデータが含まれています。

  • サイトURL、ホームURL、管理者メールアドレス、デフォルトのカテゴリ、ページごとの投稿数、時間の形式など
  • プラグイン、テーマ、ウィジェットの設定
  • 一時的にキャッシュされたデータ
wp_optionsテーブル
wp_optionsテーブル

このテーブルには次のフィールドが含まれています。中には、パフォーマンスの観点で重視する必要のある項目も一つあります。

  • option_id
  • option_name
  • option_value
  • autoload
wp_optionsテーブルの自動読込
wp_optionsテーブルの自動読込

wp_optionsテーブルについて理解しておくべき重要なポイントの一つは、autoload (動読み込み)列です。これには、yesまたはnoの値(フラグ)があり、 wp_load_alloptions() 関数にそのデータが読み込まれるかを制御します。自動読み込みデータは、WordPressウェブサイトの各ページに読み込まれているデータのことです。考え方は、特定のスクリプトがウェブサイト全体に読み込まれないようにする手順と同様です。autoload属性は、開発者向けに「yes」の基本設定になっていますが、各プラグインが各ページにそのデータ全体を読み込む必要はありません。

WordPressウェブサイトが遭遇する可能性がある問題は、wp_optionsテーブルに大量の自動読み込みデータがあるときに、WordPressウェブサイトの異常が発生する場合があります。一般的な理由は以下の通りです。

  • あるプラグインが「no」に設定すべきなのに、データが自動読み込みされています。お問い合わせプラグインがその分かりやすい例でしょう。本当に各ページでデータを読み込むべきでしょうか。それともお問い合わせのページのみで十分でしょうか。
  • あるプラグインまたはテーマは既にWordPressウェブサイトから削除されましたが、関連のオプションはまだwp_optionsテーブルに残っており、リクエスト毎に不要な自動読み込みデータに対するクエリが実行されています。
  • プラグインまたはテーマの開発者は、独自のテーブルを利用するのではなく、wp_optionsテーブルにデータが読み込まれます。開発者には追加のテーブルを作成しないプラグインがいいと言っている人もいる為、議論を双方の立場から見ることができるでしょう。一方、wp_optionsテーブルは数千行を処理するために設計されたものではありません。

自動読み込みデータはどれほどあれば多すぎるでしょうか。もちろん場合にもよりますが、300 KB~1 MBの程度は理想的です。3〜5 MBの範囲に近づくと、最適化したり自動読み込みのデータから除外したりできるものがあるでしょう。そして10 MB以上の場合には、すぐに対処する必要があります。必ずしも問題が発生することに限りませんが、手始めに実施してみましょう。

wp_optionsテーブルの自動読み込みデータのトラブルシューティング

WordPressサイトで速度が低下している場合は、古いWordPressプラグインに残されたクエリまたは自動読み込みデータが原因である可能性があります。以下では、データベースの自動読み込みデータの容量を確認する方法と、本番サイトのデータを分析して、整理する方法を案内します。

自動読み込みデータの容量を確認する

まずは、WordPressサイトの自動読み込みデータの容量を確認します。これを行うには、phpMyAdminにログインします。左側でデータベースをクリックして、「SQL」タブをクリックします。次に、次のコマンドを入力して「実行する」をクリックします。

SELECT SUM(LENGTH(option_value)) as autoload_size FROM wp_options WHERE autoload='yes';

WordPressサイトがwp_以外のプレフィックスを使用している場合は、上記のクエリを微調整する必要がある場合があります。

phpMyAdminで自動読み込みデータを確認するクエリ
phpMyAdminで自動読み込みデータを確認するクエリ

autoload_sizeはバイト単位で返されます。1KBは1024バイト、1MBは1024KBです。したがって、今回の例では、249,025バイトは0.25MBに相当します。例のサイトの場合、これは適切な容量です。1MB未満の結果が返されたら、まだ結構です。ただし、結果がはるかに大きい場合は、本記事の手順に従って、修正してください。

自動読み込みデータの容量
自動読み込みデータの容量

次の例のサイトでは、137,724,715バイト(つまり137MB)が返されました。これは、間違いなく異常で、改善の余地のある例です。

wp_optionsテーブルの自動読み込みデータの容量が大きすぎる
wp_optionsテーブルの自動読み込みデータの容量が大きすぎる

次のような長いクエリを使用することもできます。このクエリでは、自動読み込みデータの容量、テーブルのエントリ数、および容量の最も大きい10点のエントリが表示されます。

SELECT 'autoloaded data in KiB' as name, ROUND(SUM(LENGTH(option_value))/ 1024) as value FROM wp_options WHERE autoload='yes'
UNION
SELECT 'autoloaded data count', count(*) FROM wp_options WHERE autoload='yes'
UNION
(SELECT option_name, length(option_value) FROM wp_options WHERE autoload='yes' ORDER BY length(option_value) DESC LIMIT 10)
自動読み込みデータの詳細なMySQLクエリ
自動読み込みデータの詳細なMySQLクエリ

New Relic(要ライセンス)を使用して、wp_optionsテーブルに接続されたクエリのトラブルシューティングに役立てることも可能です。「データベース」タブには、最も時間のかかるテーブルとクエリの種類が表示されます。リストの項目を一つ選択すると、サンプルクエリなどの詳細情報が確認できます。下記の例では、wp_optionsテーブルの自動読み込みデータで異常が発生していることが分かります。wp_optionsテーブルを簡単に分析すると、約250 MBのデータもこのテーブルから自動読み込みされていることが確認できます。

遅いクエリの詳細情報を確認することにより、データベースのどこを探せばいいか分かります。
New Relicで見たwp_optionsテーブルの遅いクエリ

上位の自動読み込みデータの整理

次のステップは、上位の自動読み込みデータの並べ替えです。トップ10を一覧表示するために次の簡単なSQLコマンドを使用します。

SELECT option_name, length(option_value) AS option_value_length FROM wp_options WHERE autoload='yes' ORDER BY option_value_length DESC LIMIT 10;

繰り返しますが、WordPressサイトがwp_以外のプレフィックスを使用している場合は、上記のクエリを微調整する必要がある場合があります。

wp_optionsテーブルの上位の自動読み込みデータ
wp_optionsテーブルの上位の自動読み込みデータ

wp_optionsの自動読み込みデータ一つずつ分析する

次のステップは、上位の自動読み込みデータを一つずつ分析することです。

301_redirects

上記の例では、一番上の自動読み込みオプションは「301_redirects」です。これはおそらく、サイトのリダイレクトプラグイン、またはリダイレクト機能もあるSEOプラグインに関連しています。この場合、リダイレクトをサーバーレベルで実装することをお勧めします。

理由は、無料のWordPressプラグインを使用してリダイレクトを設定すると、そのリダイレクトはwp_redirect関数を使用するためパフォーマンス上の課題が発生することがよくあるためです。そしてもちろん、wp_optionsテーブルでデータの自動読み込みも発生してしまいます。

Kinstaのお客様は、MyKinstaでリダイレクトルールを追加し、サーバーレベルで簡単にリダイレクトを設定することができます。これによってパフォーマンスが向上されるだけでなく、使用するプラグインを減らすことができます。

MyKinstaでリダイレクトルールを追加
MyKinstaでリダイレクトルールを追加

wpurp_custom_template_

次の自動読み込みオプションは「wpurp_custom_template_#」です。これはかなりの数で発生しています。通常、テーマまたはプラグインフォルダーを調べることにより、このオプション名を見つけて分析できるはずです。今回の例では、サーバーからgrepコマンドを実行して、探してみました。SFTPでスポットチェックを行うこともできます。

grep -Ri "wpurp_custom_template_"

ただし、上記のコマンドでは何も返さられませんでした。したがって、Google検索を実行しました。サイトから既に削除されたWP Ultimate RecipeというWordPressプラグインに関連していることがすぐにわかりました。不要な自動読み込みデータの典型的な例です。WordPressプラグインの適切なアンインストール手順については長いチュートリアルをご用意しております。適切とは、不要なものを残さない手順です。

wpurp_custom_template_
wpurp_custom_template_

um_cache_userdata_

次の自動読み込みオプションは「 um_cache_userdata_#」です。これはかなりの数で発生しています。この項目はリストのほぼ最後の項目であったため、MySQLコマンドを変更して、自動読み込みデータのトップ40を表示するようにしました。

SELECT option_name, length(option_value) AS option_value_length FROM wp_options WHERE autoload='yes' ORDER BY option_value_length DESC LIMIT 40;

または、そのプレフィックスの値を合計します。

SELECT 'sum size in KiB', ROUND(SUM(length(option_value))/1024,0) FROM wp_options WHERE autoload='yes' AND option_name like "um_cache_userdata_%"

これで、wp_optionsテーブルにum_cache_userdata_#のエントリの数がさらに多いことがわかりました。そこで再度grepコマンドを実行し、プラグインとテーマフォルダーを確認しました。

grep -Ri "um_cache_userdata_"

Ultimate Memberプラグインに関連しているものであることをすばやく特定できました。簡単なGoogle検索を実行すると、本問題の優れた解決策がいくつか出ました。(サポート記事を参照)Google検索の力を過小評価しないでください!本問題を解決するには、プラグイン内のオプションがいくつかあったことがわかりました。

  • 「Ultimate Member」 > 「Dashboard」 (ダッシュボード)> 「User Cache」 (ユーザーキャッシュ)> 「Clear Cache」(キャッシュを削除)
  • Ultimate Member -> 「Settings」 (設定)-> 「Advanced」 (詳細設定)-> 「Stop caching user’s profile data」(ユーザーのプロファイルデータのキャッシュを停止する) をオンにして、変更を保存

自動読み込みデータオプションを確認するもう1つのやり方は、編集ボタンを押すことです。これにより、プラグインやテーマのディレクトリを一覧表示したり、開発者の各Webサイトを一覧表示したりできます。

cronジョブ

自動読み込みデータが多いときによく見られるもう1つのオプションはcronです。したがって、cronに関連していても驚くことではありません。つまり、「編集」ボタンを押して、原因を確認するだけです。以下の例では、「do_pings」が問題の原因であることが明らかになりました。繰り返しになりますが、簡単なGoogle検索を実行すると、「do_pings」を削除する手順が出てきます。

cronの「do_pings」
cronの「do_pings」

wp_optionsテーブルの整理

上記の内容が多数表示されている場合は、wp_optionsテーブルのすべての自動読み込みデータを削除する時期が来たかもしれません。wp_optionsテーブルの行数を最小限に抑えるようにすることをお勧めします。データベースのデータを削除する前に、必ずバックアップを作成してください。自信がない場合は、WordPressの開発者を雇うことをお勧めします。そして、ステージング環境があると便利です。

以前と同様に、phpMyAdminにログインします。左側でデータベースをクリックして、「SQL」タブをクリックします。次に、次のコマンドを入力して「実行する」をクリックします。

SELECT * FROM `wp_options` WHERE `autoload` = 'yes'

WordPressサイトがwp_以外のプレフィックスを使用している場合は、上記のクエリを微調整する必要がある場合があります。これにより、wp_optionsテーブルのすべての自動読み込みデータが表示されます。

wp_optionsの自動読み込みデータを見つける
wp_optionsの自動読み込みデータを見つける

クロールダウンすると、サイトからアンインストールされたプラグインまたは使用されなくなったプラグインが表示されます。本記事で使用するデータは例にすぎませんが、今回の例では、Jetpackの行が多いことに気づきました。例のサイトでは、Jetpackは使用されなくなりました。

古い自動読み込みデータ
古い自動読み込みデータ

プラグインの開発者は、残されたテーブルを削除する方法を案内している場合があるため、プラグイン開発者のドキュメントを必ず確認した方が良いです。その場合、プラグインを再度インストールして自動削除オプションを確認してから、プラグインを適切に削除した方が安全で簡単でしょう。ただし、本記事ではテーブルを手動で整理する方法をご案内します。

今回の例では、次のクエリを実行して、wp_optionsテーブルでJetpackプラグインの自動読み込みデータを検索します。クエリを調整するには、%jetpack%を置き換えるだけです。

SELECT * 
FROM `wp_options` 
WHERE `autoload` = 'yes'
AND `option_name` LIKE '%jetpack%'

次に、すべての行を選択して、「削除」をクリックします。

自動読み込みテーブルの削除
自動読み込みテーブルの削除

または、次のコマンドを実行します。

DELETE
FROM `wp_options` 
WHERE `autoload` = 'yes'
AND `option_name` LIKE '%jetpack%'
wp_optionsテーブルの自動読み込みデータの削除
wp_optionsテーブルの自動読み込みデータの削除

次に、同じことを繰り返して、wp_optionsテーブルのその他のプラグインやテーマに残された自動読み込みデータも削除できます。

一時データを削除する

オブジェクトキャッシュを採用していない限り、WordPressは一時レコードwp_optionsテーブルに保存します。これらには有効期限が設定され、時間が経つにつれ消えるはずでが、必ずしもそうとは限りません。何千もの古い一時レコードがあるデータベースをいくつか見たことがあります。一時データはデフォルトで自動読み込みされない為、ご注意ください。以下のようなクエリを実行し、自動読み込みの一時データがあるかどうかを確認します。

SELECT * 
FROM `wp_options` 
WHERE `autoload` = 'yes'
AND `option_name` LIKE '%transient%'

一方、wp_optionsテーブルから期限切れの一時データのみを削除するTransient Cleanerなどの無料のプラグインを利用することは上記よりも安全な方法です。

WordPressセッションを削除する

cronジョブがシンクロしなくなり、きちんと機能しない為、セッションは適切に削除されないこともよく発生する課題の一つです。データベースに大量の_wp_session_行があることもあります。以下の例のウェブサイトのwp_optionsテーブルに300万行以上が表示されており、テーブルのサイズは600 MB以上もしました。

wp_optionsテーブルに数百万行がある事例
wp_optionsテーブルに数百万行がある事例

以下のようなクエリを実行し、この課題が発生しているかどうかを確認します。

SELECT * 
FROM `wp_options` 
WHERE `option_name` LIKE '_wp_session_%'
_wp_session_の行
_wp_session_の行

これらは、ほとんどの場合だと、次のコマンドを実行し安全に削除できます。(本当はcronジョブがこれらを削除するはずでした。)

DELETE FROM `wp_options` 
WHERE `option_name` LIKE '_wp_session_%'

不要の_wp_session_行を削除した後、テーブルには1,000行未満が残り、サイズは11 MBになりした。

削除後のWPセッション
削除後のWPセッション

該当ウェブサイトのMySQLのばらつきも改善されました。

MySQLのWebトランザクション
MySQLのWebトランザクション

自動読み込みにインデクスを追加する

wp_optionsテーブルを整理するだけでは不十分な場合には、自動読み込み欄に「インデックス」を追加しましょう。インデクスを追加することにより自動読み込み欄がより効率的に検索されるようになります。10upのチームは、典型的な数の自動読み込みレコードを使用し、wp_optionsクエリに自動読み込みインデックスを追加するとパフォーマンスが改善することを示すためのwp_optionsテーブルの複数の試験を行いました。

wp_optionsクエリ時間
wp_optionsクエリ時間(画像出典:10up

以下のWP Bulletによる記事も必ずご確認ください。

ウェブサイトの最適化については、当社の詳細なガイド「WordPressウェブサイトのスピードUP(スーパーガイド)」をご覧ください。