web-dev-qa-db-ja.com

Wp_optionsテーブルに対するスロークエリ

WPベースのサイトのスロークエリログ(デフォルト値は a long_query_time を10に設定)を追跡してきましたが、次のクエリが頻繁にログに記録されることに気付きました -

# User@Host: root[root] @ localhost []
# Query_time: 0  Lock_time: 0  Rows_sent: 394  Rows_examined: 458
SELECT option_name, option_value FROM wp_options WHERE autoload = 'yes';

私はそのような小さなテーブルが実行するのにそれほど多くの時間がかかることができる方法を理解していません。これは他の問題の単なる症状ですか。 (現在、Moodle、phpbb、WPを専用の仮想マシンで実行しています)。

15
Prasad Ajinkya

更新 :クエリがログに記録される理由は インデックスを使用しない です。問い合わせ時間は0であり、すなわち実際には速く実行される。これらをログに記録したくない場合は、 "log-queries-not-using-indexes"オプションの設定を解除することができます。

Wp_optionsテーブルには自動ロードに関するインデックスがないため、クエリは全テーブルスキャンを実行します。一般的にそのテーブルは大きくなりすぎてはいけません、それでそれは問題ではありません、しかし、私はそれがどういうわけかあなたのケースで起こったと思います。

インデックスを追加することで問題は解決するかもしれませんが、TheDeadMedicがコメントで指摘したように、autoloadの値が大多数であるか、yesとnoの間で均等に分散されているかではありません。

まず、このクエリを実行して分布がどのように見えるかを確認します。

SELECT COUNT(*), autoload FROM wp_options GROUP BY autoload;

それらの大多数が 'no'に設定されている場合は、自動ロードにインデックスを追加することで今のところ問題を解決できます。

ALTER TABLE wp_options ADD INDEX (`autoload`);

しかし、なぜそのテーブルが大きくなりすぎたのかを理解しておく必要があるかもしれません。ひどく書かれたプラグインが何か魚っぽいことをしているのかもしれません。

16
Vinay Pai

私は数日前に私のサーバーで実行しているmytopに記載されているクエリに出会いました - そして実際には各クエリにかなりの時間(約10秒)かかりました!そのため、実際にはwp_optionsが問題のあるサイズになる可能性があります。私の場合、キャッシングプラグイン Cachify がwp_optionsの肥大化を担当しているのではないでしょうか。

この特定のwp_optionsのデータ:

5,309 rows
130MB of data

解決策として、私は問題を完璧に解決したVinay Paiが投稿した解決策に似たインデックスを追加しました。

5
Jan Papenbrock

私のwp_optionsテーブルには約235行のデータしかありませんでした。テーブルにインデックスを付けようとしましたが、役に立ちませんでした。

約150の一時的なオプションがテーブルに挿入されていたが、自動的に削除されていなかったことがわかりました。

関連があるかどうかはわかりませんが、/var/log/Apache2/access.logファイルを調べてみたところ、複数の(おそらく侵害された)Amazon Web Servicesサーバー(IPアドレスが54で始まる)に気付いていました。 XXXと32.XXX)は/~web-root-dir/xmlrpc.phpを悪用しようとしていました。

いくつかのトラブルシューティングの後、 "transient"を含むオプション名についてwp_optionsテーブルを照会しました。

wp_optionsから*を選択します。ここで、option_nameは '% transient %'のようになります。

このクエリから返されるフィールドの1つは 'option_value'で、データ型はLONG​​TEXTです。 mySQLのドキュメントによると、LONGTEXTフィールド(各行)は最大4ギガバイトのデータを保持できます。

クエリを実行したとき、一部の行( "transient"を含むもので作業していたことを覚えています)では、option_valueフィールドに 大量 のデータ量がありました。結果を調べてみると、cronサイクル中にコマンドが実行されることを期待して、wp-cronプロセスにコマンドを挿入しようとしているように見えることもわかりました。

私の解決策はすべての "一時的な"行を削除することでした。 「一時的な」行が自動的に再作成されるので(これがあると想定される場合)、これはサーバーに害を及ぼすことはありません。

これを実行した後、サーバーはもう一度応答しました。

これらの行を削除するためのクエリ:

Option_nameが '% transient %'のようなwp_optionsから削除します。

AWS IPアドレス/ 8スーパーブロックをファイアウォールに追加しました( - :

1
Ex_Military