web-dev-qa-db-fra.com

Admin: page d'édition très lente par une méta-requête principale

Nous avons remarqué des temps de chargement très longs lorsque vous modifiez un article ou une page. À l'aide du moniteur de requêtes, nous avons constaté que cette requête principale WP prend 15 à 20 secondes.

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()

Nous utilisons beaucoup de postmeta car l’un de nos types de publication utilise environ 20 champs personnalisés. Je dirais que nous comptons peut-être trop sur le postmeta, mais cela semble être une requête très inutile, car il ne s'agit même pas de sélectionner l'ID du message.

Est-ce un problème commun? Existe-t-il un moyen de désactiver cette fonction via un filtre? Merci pour toute contribution.

10
psorensen

Si vous souhaitez tester votre code SQL personnalisé pour voir comment il affecte le temps de chargement, vous pouvez essayer cette permutation de requête:

/**
 * 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;
    } );                                                            
} );

Ici, nous utilisons le hook add_meta_boxes_{$post_type}, où $post_type = 'post'.

Ici, nous échangeons toute la requête, mais nous aurions aussi pu l'ajuster pour prendre en charge la limite dynamique.

J'espère que vous pourrez adapter cela à vos besoins.

Mettre à jour:

Cette requête principale SQL potentiellement lente a maintenant été ajustée dans WP version 4.3 à partir de

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;

Découvrez le ticket de base # 24498 pour plus d'informations.

5
birgire

Si vous parcourez le code source de la fonction, vous trouverez ceci:

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

En utilisant le hook postmeta_form_keys, vous pouvez spécifier manuellement les clés pour éviter d'appeler complètement cette requête inefficace:

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

Pouvez-vous essayer ceci. Ce n'est pas une solution, mais une solution temporaire.

// 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
prosti