管理者:コアメタクエリが原因で非常に遅い編集ページ


11

投稿やページを編集しようとすると、ロード時間が非常に長くなることに気づきました。クエリモニターを使用して、このWPコアクエリが15〜20秒に増加していることがわかりました。

SELECT meta_key 
FROM wp_postmeta 
GROUP BY meta_key 
HAVING meta_key NOT LIKE '\\_%' 
ORDER BY meta_key 
LIMIT 30

caller: 
meta_form()
post_custom_meta_box()
do_meta_boxes()

投稿タイプの1つが約20程度のカスタムフィールドを使用するため、私たちは多くのpostmetaを使用しています。おそらくpostmetaに依存しすぎているかもしれませんが、これは投稿のIDを選択することすらしないので、非常に効率の悪いクエリのように見えます。

これは一般的な問題ですか?フィルターを介してこの機能を無効にする方法はありますか?ご意見をお寄せいただきありがとうございます。


これは、プラグインとデフォルトのテーマなしで起こりますか?
バージィ

はい、そうです。上記のように、遅いクエリはWPコアに属するものとして識別しました。私が提供した回答の関数では、カスタムフィールドのメタボックスが無効になっているため、クエリを実行できません。
psorensen

2
私はそれを知っているのを見て、私はmeta_form()関数をチェックアウトしました、そしてこれは確かにそのコア関数から生成されたSQLクエリです。でコードを変更して独自のカスタムメタボックスを追加し、meta_form()そこで提案されたSQLクエリを使用することができます。この#8561クローズドトラックチケットを見つけました。別のチケットを作成するか、このチケットを再度開こうとしますか? PS:メタボックスを選択する親ページにも問題があることに注意してください。100万ページを取得した場合、それらのすべてが選択オプションとして表示されます。
2015年

2
CSS-トリックに提案されたソリューション:css-tricks.com/...
psorensen

興味深いソリューションですが、meta_form()関数全体を置き換えているようです。回答を更新しました-コアSQLクエリはWPバージョン4.3で調整されています。この新しいSQLクエリを使用すると、追加のpost_id制限と比較してパフォーマンスが向上しますか?
バージィ

回答:


5

ロード時間にどのように影響するかを確認するためにカスタムSQLをテストする場合は、次のクエリスワッピングを試すことができます。

/**
 * Restrict the potential slow query in the meta_form() to the current post ID.
 *
 * @see http://wordpress.stackexchange.com/a/187712/26350
 */

add_action( 'add_meta_boxes_post', function( $post )
{
    add_filter( 'query', function( $sql ) use ( $post )
    {
        global $wpdb;
        $find = "SELECT meta_key
                 FROM $wpdb->postmeta
                 GROUP BY meta_key 
                 HAVING meta_key NOT LIKE '\\\_%'
                 ORDER BY meta_key 
                 LIMIT 30";
        if(    preg_replace( '/\s+/', ' ', $sql ) === preg_replace( '/\s+/', ' ', $find )
            && $post instanceof WP_Post  
        ) {
            $post_id = (int) $post->ID;
            $sql  = "SELECT meta_key
                     FROM $wpdb->postmeta
                     WHERE post_id = {$post_id}
                     GROUP BY meta_key
                     HAVING meta_key NOT LIKE '\\\_%'
                     ORDER BY meta_key
                     LIMIT 30";
        }
        return $sql;
    } );                                                            
} );

ここでは、add_meta_boxes_{$post_type}フックを使用してい$post_type = 'post'ます。

ここではクエリ全体を交換しますが、動的制限をサポートするように調整することもできます。

うまくいけば、必要に応じてこれを調整できます。

更新:

この潜在的に遅いSQLコアクエリは、WPバージョン4.3で調整されました。

SELECT meta_key 
FROM wp_postmeta 
GROUP BY meta_key 
HAVING meta_key NOT LIKE '\\_%' 
ORDER BY meta_key 
LIMIT 30

に:

SELECT DISTINCT meta_key
FROM wp_postmeta
WHERE meta_key NOT BETWEEN '_' AND '_z'
HAVING meta_key NOT LIKE '\_%'
ORDER BY meta_key
LIMIT 30;

詳細については、コアチケット#24498を確認してください。


2

関数のソースコードを参照すると、次のことがわかります。

$keys = apply_filters( 'postmeta_form_keys', null, $post );
if ( null === $keys ) {
    ...      
}

postmeta_form_keysフックを使用すると、手動でキーを指定して、この非効率的なクエリをまったく呼び出さないようにすることができます。

add_filter('postmeta_form_keys', function(){
    return ['your_meta_key'];
});

面白い。これはソースコードのどこに存在しますか?
psorensen

wp-admin / includes / template.php:595(4.4以降)
markdwhite

2

これを試して頂けますか?これは解決策ではなく、一時的な回避策です。

// disable big slowdown http://wordpress.stackexchange.com/questions/187612/admin-very-slow-edit-page-caused-by-core-meta-query
function dj_limit_postmeta( $string, $post ) {
    return array(null);
}
add_filter( 'postmeta_form_keys', 'dj_limit_postmeta', 10, 3 );

-1

メタボックスを削除すると、クエリが遅くなることも防げます。

function remove_metaboxes() {
     remove_meta_box( 'postcustom', 'page', 'normal' );
}
add_action('admin_menu', 'remove_metaboxes');
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.