サポート » 使い方全般 » インストール直後からデータベースクエリが遅い

  • 解決済 developer

    (@6flat)


    Query MonitorというプラグインでWordPressをインストールした直後のパフォーマンスを見ていたのですが、Query Monitorをインストールした以外は何もしていないにも関わらずSlow Queriesの警告が1つ出ていました。

    内容を見てみると、wp_load_alloptions(), is_blog_installed(), wp_not_installed()が呼び出されていて、そのクエリに約0.1sかかっています。
    なお、他のクエリは平均して大体0.0004sです。

    wp_load_alloptions()がオプションを読み込んでいるのは分かるのですが、オプションを読み込むだけで何故こんなに遅いのか分からず、またこれを改善しようにもどうすれば良いのか全く分かりません。
    また、is_blog_installed()はともかくwp_not_installed()がインストール後に実行されるのも意味が分かりません。

    色々と検索もしてみたのですが、改善に繋がりそうな情報が見つからずに困っています。

    ちなみにインストールしたサーバはさくらのスタンダードで、環境はPHP5.6.10、MySQL5.5.38です。

    何か原因の予測や改善に繋がるアドバイスなどを頂けたら非常に助かります。
    よろしくお願い致します。

    追記
    次の様な内容がQuery Monitorによって表示されていました。

    [Query]
    SELECT option_name, option_value
    FROM database_options
    WHERE autoload = 'yes'
    
    [Caller]
    wp_load_alloptions()
    is_blog_installed()
    wp_not_installed()
    
    [Component]
    Core
    
    [Affected Rows]
    114
    
    [Time]
    0.1044

    そして、データベースからoptionsテーブルを開いて114行目を見てみました。

    [option_name]
    _transient_feed_ab995de7a5278071ed721c721c891aed
    
    [option_value]
    バージョンアップの時に表示されるページのフィード(全文)?
    
    [autoload]
    no

    …やっぱりよく分かりません。

12件の返信を表示中 - 1 - 12件目 (全12件中)
  • 遅い理由については何とも言えませんが…
    Affected Rows の 114 は、実行されたクエリが114行を返したということなので確かに遅いですね。私もさくらのスタンダードですが 516 rows で 0.0060 秒です。

    それから wp_load_alloptions(), is_blog_installed(), wp_not_installed() と上から順に三つ表示されるのは、wp_not_installedがis_blog_installedを呼び出して、is_blog_installedがwp_load_alloptionsを呼び出していることを表しているのでしょう。wp_not_installedはインストール後も必ず呼び出されます(index.php → wp-blog-header.php → wp-load.php → wp-config.php → wp-settings.php の中で wp_not_installed を呼んでいます)。

    gblsmさん、ご回答ありがとうございます。
    wp_load_alloptions()が他2つの関数を呼び出しているんですね…。
    何かの不具合なのではないかと思っていましたが安心しました。

    あれからデータベースの内容を一度削除してからPHPを5.4に戻してみたり、それに合わせてデータベースの文字セットをutf8mb4_general_ciからutf8_general_ciに戻してみたりしましたがクエリは遅いままです。
    そして遅い原因となっているのもやはりwp_load_alloptions()です。
    ただ、今度はtransient_feed_ab995de7a5278071ed721c721c891aedではなく、その一つ下の_transient_timeout_feed_mod_ab995de7a5278071ed721c721c891aedという行でした。

    今はさくらに一応問い合わせてみたところなので、その返答を待ちながら検索して原因を調べています。

    6flat さん、その一行をクエリで取得するのに要する時間が遅いのではなく、114行(Affected Rowsの数値)全部を取得するのに要した時間が約 0.1 秒という測定結果なんだと思いますよ。さくらのスタンダードはMySQLが別の共用サーバーにあるので、その共用サーバーで 6flat さんではない人が何か負荷の高い処理(別のクエリ)を実行させているのかもしれませんね。

    テーブルの位置を指しているわけではないんですね…。
    もしDBサーバーの同居人が高負荷をかけているのなら、DBサーバーを変えてもらうくらいしか出来る事は無さそうですね。

    追記
    現状のまとめ

    • wp_load_alloptions()を呼び出した時のクエリ実行時間が遅い(0.1s)
    • wp_load_alloptions()はデータベースのwp_optionsテーブルにあるautoload=’yes’となっているものを全て読み込んでいる
    • この読み込みに時間がかかっている
    • 通常、この読み込みにこれほど時間が掛かる事はない

    この点を中心に調べていこうと思います。

    更に追記
    performance – Slow Query for the wp_options table – WordPress Development Stack Exchange
    WordPress wp_options table autoload micro-optimization – Sysadmins of the North
    上記リンクを参考に以下のSQLを実行してみましたが、改善されませんでした。
    ( ` を ‘ に置き換えています)
    ALTER TABLE 'wp_options' ADD INDEX ('autoload')

    wp_load_alloptions()で実行されているであろう次のSQLをphpMyAdminから実行すると実行時間は0.0015sと全く問題ありませんでした。

    SELECT option_name, option_value FROM wp_options WHERE autoload = 'yes'

    …もしかするとQuery Monitorプラグインそのものが原因なのでしょうか。
    このプラグインの追加以外には何も手を加えていないので、何だかそんな気がしてきました。

    もう一度次のSQLを実行すると実行時間が0.1135sとなり、やはり遅い結果が出ました。

    SELECT option_name, option_value FROM wp_options WHERE autoload = 'yes'

    あとはデータベースの状態を見てみると、確かに負荷が高い状態なのかもしれないと感じました。
    全く詳しくないので赤文字になっているところだけ見てそう感じただけですが…。

    Slow_queries: 3,826
    
    Innodb_buffer_pool_pages_dirty: 1,215
    Innodb_beffer_pool_reads: 19M
    Innodb_log_waits: 1
    Innodb_row_lock_time_avg: 233
    Innodb_row_lock_time_max: 26k
    Innodb_row_lock_waits: 47k
    
    Handler_read_md: 61G
    Handler_read_md_next: 7,716G
    
    Qcache_lowmen_prunes: 417M
    
    Created_tmp_files: 338M
    
    Select_full_join: 3,069k
    Select_range_check: 20k
    
    Sort_merge_passes: 2,502k
    
    Opened_tables: 4,295k
    Table_locks_waited: 71k

    何故か投稿が反映されないのでもう一度まとめます。

    私に今起こっている問題は、wp_load_alloptions()が呼び出される時に通常はオブジェクトキャッシュを利用するはずが、何らかの問題でオブジェクトキャッシュを取得できないために都度DBにクエリを送ってwp_optionsテーブルから100以上のデータを取得しているという事が原因の様です。

    これはマルチサイト機能を使うと起こる事らしいですが、私はマルチサイトは利用していませんし、新規インストールしたWordPress以外には何も無い状態なので、何が原因なのか私の知識では皆目見当がつかず、困り果てています。

    何か原因に見当のつく方が居られたらお力添えを頂けると助かります。

    根本的なお話ですが
    やっぱり共有サーバーを使っていれば、共有サーバー内でほかのユーザーに引っ張られたりって可能性はないとも言えません。

    一度、体験試用期間とか利用して試してみてはいかがでしょう。
    好みや価格帯などあるかとは思いますが無難なところで

    Xserver
    http://www.xserver.ne.jp/feature/

    また、サーバーのPHPのバージョンなどサーバー周りの設定も視野に入れたほうが良いかもしれません。

    mura0403さん、ご回答ありがとうございます。
    サポートに問い合わせたのですが、データベースサーバで支障が出る様な過負荷はないという返答でした。
    過負荷の無い状態でも他のユーザーから何らかの影響を受けるものなのでしょうか…?
    出来る事ならサーバを変えたくはないのですが…選択肢として一応考えておきます。

    前に一度、会社で使っているホスティングで何をやっても遅いと思って
    問い合わせたら、しばらくたった後に回答で
    ほかの使用者で過負荷がかかりっていう原因がありました。

    まれなケースかもしれませんが
    そうですよね、サーバー変えるのはいろいろな面で大変ですからね。

    お試しで同じスタンダードプランの別のサーバを借りてWordPressをインストールしてみましたが、同じくwp_load_alloptions()で負荷の高いクエリが実行されました。
    gblsmさんと私の違いは一体何なのでしょうか…。

    option.phpにあるwp_load_alloptions()と全く同じ関数を作った上で内容を書き換えて実行結果を見てみましたが、キャッシュ自体は取得出来ている様でした。

    function test_load_alloptions() {
    	global $wpdb;
    
    	if ( !defined( 'WP_INSTALLING' ) || !is_multisite() ) {
    		$alloptions = wp_cache_get( 'alloptions', 'options' );
    		echo 'cache get';
    		var_dump( $alloptions );
    	} else {
    		$alloptions = false;
    	}
    // 省略
    }

    別の処理でキャッシュが破棄されているのでしょうか…。
    get_option()の内部でもwp_load_alloptions()が呼び出されている様なので、こちらも確認してみようと思います。

    解決しました。
    結論から言うと、原因はQuery Monitorでした。

    あれこれ調べているうちにDebug Barというプラグインを見つけ、また次のページに辿り着きました。

    Debug BarとDebug-Bar-ExtenderでWordPressのパフォーマンスチェック | Simple Colors

    まさかと思い、Query Monitorを停止してDebug Barのみでクエリを確認したところ、原因のクエリがクエリの一覧から消えました。
    この時は思わず乾いた笑いがこみ上げてきました。
    こんなところでjim912さんのお世話になるとは思いませんでしたが、本当に助かりました。
    回答して下さったお二方とjim912さんには心からお礼申し上げます。
    本当にありがとうございました。

12件の返信を表示中 - 1 - 12件目 (全12件中)
  • トピック「インストール直後からデータベースクエリが遅い」には新たに返信することはできません。