この記事は最後に更新してから1年以上経過しています。
説明
「5.3 RC2」が公開され、正式リリースまであと20日。公式ディレクトリにプラグインを公開していることもあり、5.3に関する開発者向けの情報「Miscellaneous Developer Focused Changes in 5.3」を読んでいる。
ちょっと気になる'log_query_custom_data'フィルター
このページでは register_post_type関数や add_theme_support関数の変更内容に続いて記載されていた「Recording Additional Information For Saved Queries.」の項目が気になった。
WordPressはwp-config.phpに次の記述を指定することで、
$wpdb->queries
(配列)にデータベースに対して実行したクエリー情報を保持する仕組みがある。
define( 'SAVEQUERIES', true );
テーマのfooter.phpの適当なところに次の記述を追加する。
<?php print_r( $GLOBALS['wpdb']->queries ); ?>
5.2.4でサイトのトップページを表示すると、フッターには次のような内容が出力される(抜粋)。
Array
(
[0] => Array
(
[0] => SELECT option_name, option_value FROM wp_options WHERE autoload = 'yes'
[1] => 0.00094008445739746
[2] => require('wp-blog-header.php'), require_once('wp-load.php'), require_once('wp-config.php'), require_once('wp-settings.php'), wp_not_installed, is_blog_installed, wp_load_alloptions
[3] => 1571819572.1011
)
[1] => Array
(
[0] => SELECT * FROM wp_users WHERE user_login = 'xxxxxxxx' LIMIT 1
[1] => 0.00076103210449219
[2] => require('wp-blog-header.php'), require_once('wp-load.php'), require_once('wp-config.php'), require_once('wp-settings.php'), WP->init, wp_get_current_user, _wp_get_current_user, apply_filters('determine_current_user'), WP_Hook->apply_filters, wp_validate_logged_in_cookie, wp_validate_auth_cookie, get_user_by, WP_User::get_data_by
[3] => 1571819572.3205
)
:
1つ1つのクエリー情報は、キー0がクエリー文、キー1が実行時間(秒)、キー2が関数の呼び出し情報(カンマ区切り)、キー3が開始時刻(秒)となっている。
5.3では、'log_query_custom_data'フィルターを使用することで任意の情報(配列)が保持できるようになる。次のコードを追加してAJAXリクエストか判別する情報を追加してみよう。
function my_log_query_custom_data( $query_data, $query, $query_time, $query_callstack, $query_start ) {
$query_data['AJAX'] = wp_doing_ajax()? 1: 0;
return $query_data;
}
add_filter( 'log_query_custom_data', 'my_log_query_custom_data', 10, 5 );
5.3.0 RC2でサイトのトップページを表示してみると、フッターには次のような内容が出力される(抜粋)。
Array
(
[0] => Array
(
[0] => SELECT option_name, option_value FROM wp_options WHERE autoload = 'yes'
[1] => 0.0012838840484619
[2] => require('wp-blog-header.php'), require_once('wp-load.php'), require_once('wp-config.php'), require_once('wp-settings.php'), wp_not_installed, is_blog_installed, wp_load_alloptions
[3] => 1571820657.1323
[4] => Array
(
)
)
[1] => Array
(
[0] => SELECT * FROM wp_users WHERE user_login = 'xxxxxxxx' LIMIT 1
[1] => 0.00050902366638184
[2] => require('wp-blog-header.php'), require_once('wp-load.php'), require_once('wp-config.php'), require_once('wp-settings.php'), WP->init, wp_get_current_user, _wp_get_current_user, apply_filters('determine_current_user'), WP_Hook->apply_filters, wp_validate_logged_in_cookie, wp_validate_auth_cookie, get_user_by, WP_User::get_data_by
[3] => 1571820657.3485
[4] => Array
(
[AJAX] => 0
)
)
:
各クエリー情報のキー4には配列が追加され、1つ目のクエリー情報は(フィルターの適用前なので)空の配列が、2つ目にはキー'AJAX'に値0が格納されている。このようにキー4に格納される配列は、'log_query_custom_data'フィルターを追加したタイミングの影響を受ける。
'log_query_custom_data'フィルターでログ出力
'log_query_custom_data'フィルターは本来の主旨と違う気がするが、クエリーを実行した直後にそのクエリー情報をログファイルに出力することも可能だ。
まずはwp-config.phpの内容から('WP_DEBUG_LOG'に指定するログファイルのパス名は適宜修正)。
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', '/var/www/html/wp-content/debug.log' );
define( 'SAVEQUERIES', true );
次にテーマのfunctions.phpの追記。こちらはログファイルに出力する内容によって変わるが、ここでは実行時間を示すパラメータ$query_timeを判定し、2秒以上の場合は余分な空白文字を除去したクエリー文、実行時間、関数の呼び出し情報をログファイルに出力している。
function my_log_query_custom_data( $query_data, $query, $query_time, $query_callstack, $query_start ) {
if ( 2.0 <= $query_time ) {
error_log( trim( preg_replace( '/\s+/', ' ', $query ) ) );
error_log( sprintf( '%.2f', $query_time ) .'s # ' . $query_callstack );
}
return $query_data;
}
add_filter( 'log_query_custom_data', 'my_log_query_custom_data', 10, 5 );
余裕があればテーマのfunctions.phpではなく、プラグインによる実装がよいとは思うが、本番環境が重くなり、取り急ぎ原因を調べる一環で「重いクエリー」を探す場合は、このような方法も有効だろう。
最終更新 : 2019年10月23日 20:20
関連
お勧め
delete_post_meta(2018年5月27日 更新)
wp_is_numeric_array(2018年5月27日 更新)
get_tag_regex(2013年8月3日 更新)
get_all_page_ids(2012年5月30日 更新)
the_post_thumbnail_caption(2018年5月27日 更新)