クライアントから管理画面の遅さ、決済の失敗、不規則なタイムアウトなどの報告を受けた際、何十ものテーブルを調べたり、プラグインの動作を解析したりする余裕はありません。障害の可能性が高いポイントをいち早く認識し、重要な部分に注意を集中する必要があります。

深刻なパフォーマンスと安定性に関する問題のほとんどは、時間とともに見落とされ、蓄積されていく少数のデータベーステーブルにまで遡るのが一般的です。これらのテーブルは、新規サイトやトラフィックの少ないサイトでは問題になりませんが、長年のコンテンツ、プラグイン、ユーザーアクティビティにより、正常でない数のクラッシュ、遅いクエリ、緊急の問い合わせ対応の原因になっています。

今回は、Web制作会社・管理代行会社が積極的に監視すべき5つのWordPressデータベーステーブル(およびテーブルパターン)をご紹介します。

データベーステーブルはすべてを監視する必要なし

パレートの原則(全体の成果や問題の多くは、原因の一部に集中するという考え方)は、多くの運用上の傾向を説明するのに役立ち、WordPressのデータベースメンテナンスにも当てはまります。問題はデータベース全体で均等に起きるわけではなく、実際にはデータベース起因の表示遅延やクラッシュ、緊急の問い合わせの大半は、限られた一部のテーブルに集中します。

標準的なWordPressサイトでは、12のデフォルトテーブルが生成されます。wp_userswp_links、タクソノミーテーブルなどのいくつかは、問題になることなく何年も運用可能です。通常、トラフィックの急増時にサイトをクラッシュさせるような遅いクエリを引き起こすことはありません。

注意が必要なテーブルには1つの特徴があります。投稿数が100件のサイトであれば、リビジョンに制限をかけなくても問題なく運営できるかもしれませんが、投稿数が1万件、リビジョンが30万件になると、すべての編集画面でタイムアウトが発生する可能性が高くなります。また、商品数が50点のECストアではうまく動作しても、商品数が5,000点に増えると、ページの読み込みが数秒かかるようになることがあります。

サイトの規模拡大時に起きがちなWordPressデータベースの問題パターン5選

制作会社・サイト管理代行会社におけるメンテナンス業務で、頻繁に発生する5つのテーブル(パターン)があります。

これからご紹介するパターンは、小規模なサイトではすぐに問題になるわけではありませんが、コンテンツやトラフィック、プラグインが増えるにつれ、遅いクエリやタイムアウト、安定性の問題の典型的な原因になります。

wp_options─autoloadの肥大化による高トラフィックサイトのクラッシュ

wp_optionsテーブルは、サイト設定とプラグインの設定を保存し、WordPressがすべてのページリクエスト(キャッシュページを含む)で読み込むオプションを決定します。カラムの中で最も重要になるのが、autoloadです。

多くのカラムを持つwp_optionsテーブル(MyKinstaデータベーススタジオ)
多くのカラムを持つwp_optionsテーブル(MyKinstaデータベーススタジオ)

WordPressはまず、リクエストごとにすべてのautoload(自動読み込み)オプションをメモリに読み込みます。autoloadのフットプリントが小さいサイトは、通常トラフィックを処理できますが、大きくなるにつれて、各訪問者はPHPプロセスごとにサーバーが割り当てるメモリよりも多くのメモリを消費するようになります。

autoloadのサイズが大きくなり過ぎると(例えば3MB以上)、管理画面の表示速度が遅くなったり、決済に失敗したり、502エラーが発生したりします。

ほとんどの場合、プラグインの設定や一時的なキャッシュエントリ(transients)が原因です。autoloadが有効になっていると、削除したプラグインオプションがwp_optionsテーブルに残ることがあります。数ヶ月から数年にわたって何十ものプラグインを使用すると、すべてのページビューで読み込まれる放棄されたデータが蓄積されます。

データベーススタジオのSQLコンソール
データベーススタジオのSQLコンソール

データベーススタジオのSQLコンソールでは、クエリを実行して自動読み込みされたデータサイズをバイト単位で確認できます。

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)

このコンソールを使って、最初のクエリの結果を並び替えるなど、必要なクエリを実行することも可能です。

データベーススタジオでwp_optionsテーブルからレコードを削除
データベーススタジオでwp_optionsテーブルからレコードを削除

結果を確認し、どの大きなautoloadエントリーが関連しているかを特定し、クリーンアップ(行を削除)しましょう。

wp_postmeta─メタデータの肥大化によるECサイトのクラッシュ

wp_postmetaテーブルには、投稿、固定ページ、商品のカスタムフィールドが保存されます。コンテンツが保存されるたびに、メタデータ項目が追加される可能性があります。特にプラグインは、1つの投稿や商品に何十ものフィールドを追加することも珍しくありません。

例えば、WooCommerceでは商品データ(バリエーション、在庫、配送の詳細、属性など)がpostmetaに保存されます。バリエーションを持つ商品1点だけでも、数十件のメタデータが生成されることがあります。そのため、商品点数が多い場合は、postmetaの行数が数百万規模に膨らむ可能性があります。

wp_postmetaテーブルが膨れ上がると、編集画面の読み込みと商品フィルターの読み込みが遅くなり、検索は巨大なテーブルを横断するクエリを試みる間にタイムアウトするようになります。一般的に、トラフィックの多い時期のエラーは、wp_postmetaの肥大化が原因です。

SQLコンソールを使用すると、wp_optionsと同様に、クエリを実行して余分なデータを選択・削除することができます。数ギガバイトのpostmetaテーブル、重複したmeta_keysの多さ、一般的な孤立したメタデータなどを探します。MyKinstaのデータベーススタジオでは、フィルタリングオプションが便利です。

データベーステーブルに適用されているフィルター一覧
データベーステーブルに適用されているフィルター一覧

例えば、列の矢印をクリックすると、meta_keyで並び替えることができます。同じキーがグループ化されるため、削除されたプラグインのキーや未使用のカスタムフィールドなどのパターンを見つけることが可能です。

wp_posts─無制限のリビジョンが編集画面を圧迫

wp_postsテーブルには、コンテンツとリビジョンの履歴が保存されます。デフォルトでは、WordPressはすべての変更を個別のデータベースエントリとして保存するため、通常のコンテンツ編集でかなりの量の余分なデータが生成されます。広範なコンテンツと編集履歴を持つサイトでは、何千ものリビジョンエントリが蓄積されている可能性があります。

最初のうちは、サイトが問題なく動作しても、保存されるリビジョンが増えると、投稿の編集時に管理画面の読み込みが遅くなる場合があります。WordPressは編集内容を60秒ごとに保存するため、長時間編集を行う際は何十もの自動保存エントリが生成されるため、自動保存も悪影響を及ぼすかもしれません。

wp_postsテーブルのリビジョンは、以下のように簡単に削除可能です。

wp_postsフィルターを使ってリビジョンの投稿タイプのみを表示し、さまざまなカラムで異なるデータベースのメタデータを表示
wp_postsフィルターを使ってリビジョンの投稿タイプのみを表示し、さまざまなカラムで異なるデータベースのメタデータを表示

それからSQLコンソールに切り替えてクエリを実行し、リビジョンを削除できます。

DELETE FROM wp_posts WHERE post_type="revision";

リビジョンの数を公開済みの投稿と比較して、リビジョンが総エントリの半分以上を占めているかどうかをチェックしてみてください。前月比でリビジョンが増加している場合は、リビジョンを制限することをおすすめします。wp-config.phpを簡単に編集するだけで実行できます。

プラグインのテーブル─フォームとログの肥大化によるサイトクラッシュ

ほぼすべてのプラグインがカスタムデータベーステーブルを生成しますが、フォーム、検索、セキュリティプラグインでは特に顕著で、組み込みのメンテナンスを必要とせずに成長し続ける可能性があります。

特に、フォームプラグインはデフォルトですべての投稿を恒久的に保存します。そのため、サイトが何年にもわたって安定した投稿トラフィックを受けていれば、何千ものフォームエントリが蓄積されています。さらに、ログ系のテーブルはさらに速いペースで肥大化します。たとえば、セキュリティプラグインは訪問者の行動を記録し、分析プラグインはページビューを追跡し、デバッグツールはエラーを蓄積していきます。

多くのデータベーステーブルの問題と同様に、表面的にはページのタイムアウトとして現れます。しかし実際には、データベースのバックアップに時間がかかる、トラフィック量とは無関係にパフォーマンスが低下するといった症状も起こります。データベースの肥大化が原因だとしても、影響が別の箇所に出やすいため、因果関係は一見分かりにくいことがあります。

WordPressのコアテーブルのサイズと同じか、それを超えているプラグインテーブルを探すのがおすすめです。SQLクエリで特定することができます。

SELECT
  TABLE_NAME AS `Table`,
  ROUND((DATA_LENGTH + INDEX_LENGTH) / 1024 / 1024) AS `Size (MB)`
FROM
  information_schema.TABLES
WHERE
  TABLE_SCHEMA = "{database_name}"
ORDER BY
  (DATA_LENGTH + INDEX_LENGTH)
DESC;

これらのうち孤児データ(参照先のないデータ)が含まれている場合は、安全に削除できます。今回扱う内容の範囲外になりますが、サイト運用上まだ必要なテーブルが削減が必要なほど肥大化している場合は、その原因を調査して、必要に応じて開発者に相談することをおすすめします。

Action Scheduler─失敗したタスクの蓄積による決済ページのクラッシュ

Action Schedulerは、基本的にWordPressのバックグラウンドタスクを実行します。タスクをキューに入れ、非同期で処理し、デフォルトでは完了記録を永久に保存します。

WooCommerceは、Action Schedulerがどのように問題を引き起こし得るかを理解するうえで分かりやすい例です。たとえば決済ゲートウェイのタイムアウトが発生すると、その処理は失敗したアクションとしてデータベースに残り、保留中の作業を確認するために、ページが読み込まれるたびにクエリされます。一般的なWooCommerceストアでは、こうした失敗アクションが月に数千件発生することもあり、そのうちの1件だけが残っていても影響が出る可能性があります。

データベーススタジオのViews機能を使用すると、このような失敗したアクションを削除できます。

MyKinstaデータベーススタジオのViews画面
MyKinstaデータベーススタジオのViews画面

このビューにタイトルを付け、wp_actionscheduler_actionsテーブルを選択し、「Add condition(条件を追加する)」をクリックします。これにより、失敗したアクションのみを表示することができるため、データベースからより効率的に削除できます。

月10分でできるWordPressデータベーステーブル管理の最適化

毎月10分程度の時間を割くことで、年間のデータベース管理の回数を減らすことができます。もちろん、データベース内のテーブルすべてを監視・管理する必要はありません。

  • wp_usersテーブル:何百万ものアカウントを持つ会員制サイトのような場合を除いて、問題が発生することはほぼなし。ユーザーデータは通常、肥大化することなく直線的に増加する。
  • タクソノミーテーブル(wp_termswp_term_taxonomywp_term_relationshipsなど):一般的にサイトの規模を問わず安定している。

5つの問題テーブルのうち、コンテンツサイトでwp_postsテーブルが大きくなるのは典型的で、ある程度は想定内です。実際のコンテンツそのものが「肥大化」しているわけではないという点は覚えておいてください。

監視ワークフローを作成する

データベースのテーブルをエクスポートすると、他のアプリケーションでデータを扱うことができます。MyKinstaのデータベーススタジオでは、右上の3つの点をクリックします。

MyKinstaデータベーススタジオでテーブルをエクスポート
MyKinstaデータベーススタジオでテーブルをエクスポート

エクスポートしなくても、MyKinsta上でさまざまなタスクを実行できます。なかでも時間を有効に使えるのは、クリーンアップの自動化と、データベース指標の確認です。データベーススタジオのViews機能は、分析のセットアップに役立ちます。

例えば、wp_postmetaを監視するカスタムビューを作成し、追跡したい特定のmeta_keyパターンのフィルターを追加することができます。

データベーススタジオでwp_postmetaテーブルのビューを作成
データベーススタジオでwp_postmetaテーブルのビューを作成

データベーススタジオでは、SQL コンソールにスニペットを作成して保存できるため、すべてのテーブルをサイズ順に並び替えるSQLクエリを設定して、必要時にいつでもアクセスすることができます。

データベーススタジオのコンソールでSQLスニペットを作成
データベーススタジオのコンソールでSQLスニペットを作成

最大規模のテーブルは、通常wp_postswp_postmetawp_optionsです。これ以外のテーブルが上位に入っている場合は、原因を調査してみてください。

適切な監視ワークフローは、サイトや要件によって異なりますが、以下の領域を調査する必要があります。

  • wp_optionsのautoloadが有効な項目をフィルタリングし、合計サイズを確認(SQLクエリを使用するか、CSVにエクスポート)1MBを超えるものは調査が必要。
  • wp_postmetaテーブルのサイズを先月と比較し、大きくなっていないかを確認
  • リビジョンと投稿を比較するため、wp_postspost_typeをフィルタリングする。必要に応じて、wp-config.phpでリビジョンを制限。
  • Action Schedulerでは、完了したアクションが保留中または失敗したアクションを上回っていることを確認。

まとめると、データベーススタジオを使って、よく使用するビュー、フィルター、クエリスニペットを作成します。次に、「危険な」指標を探し、他のツールを使ってクリーンアップを自動化します。例えば、wp transient deleteWP-CLIコマンドは、データベース内の不要なtransientsを取り除くのに役立ちます。

場当たり的な修正から、先回りのデータベース保守へ

Web制作会社・サイト管理代行会社が頻繁に直面するデータベースの問題は、珍しいものでも予測不能なものでもなく、よくあるパターンの延長で起きているのが一般的です。対応と予防の違いは、どこに集中するかです。

すべてのテーブルを検査したり、すべてのクエリを監査したりする必要はなく、継続的に注意すべき箇所を見極め、停止や緊急対応に発展する前に、早期の兆候を捉える方法を心得ることが重要です。

保守管理を担う制作会社にとって重要なのは、データベース対応をワークフローに組み込むことです。何かが壊れた後の一時的な対処としてクリーンアップを行うのではなく、手間の少ないチェックを定期的に行う形にします。

最後に、それでも原因の特定が難しいデータベースの問題に遭遇することもあります。特に、高負荷時にのみ表面化するようなケースでは、適切なサポート体制が重要です。Kinstaでは、エンジニアのみで構成されたカスタマーサポートに24時間365日問い合わせることができます。平均応答時間は2分以内を記録しているため、緊急時の対応も安心です。

Joel Olawanle Kinsta

Kinstaでテクニカルエディターとして働くフロントエンド開発者。オープンソースをこよなく愛する講師でもあり、JavaScriptとそのフレームワークを中心に200件以上の技術記事を執筆している。