Amministratore: pagina di modifica molto lenta causata dalla meta query principale


11

Abbiamo notato tempi di caricamento molto lunghi durante la modifica di un post o di una pagina. Utilizzando Query Monitor, abbiamo scoperto che questa query core WP impiega fino a 15-20 secondi.

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

Usiamo molto postmeta poiché uno dei nostri tipi di post utilizza circa 20 campi personalizzati. Direi che forse facciamo troppo affidamento su postmeta, ma questa sembra una domanda molto inefficiente, visto che non sta nemmeno selezionando l'ID del post.

E 'un problema comune? C'è un modo per disabilitare questa funzione attraverso un filtro? Grazie per qualsiasi input.


Questo succede senza plug-in e tema predefinito?
birgire,

Sì lo fa. Come accennato in precedenza, ho identificato la query lenta come appartenente al core WP. Con la funzione nella risposta che ho fornito, la meta-casella dei campi personalizzati è disabilitata, il che impedisce l'esecuzione della query.
psorensen,

2
Lo vedo sapere, ho appena verificato la meta_form()funzione e questa è davvero la query SQL generata da quella funzione principale. Potresti provare ad aggiungere il tuo metabox personalizzato con modifiche al codice meta_form()e utilizzare lì la tua query SQL suggerita. Ho trovato questo ticket trac chiuso # 8561 . Potresti forse creare un altro biglietto o provare a riaprirlo? PS: Notare che anche la pagina padre che seleziona metabox è problematica. Se hai 1 milione di pagine, tutte verranno visualizzate come opzioni selezionate!
birgire

2
Una soluzione proposta su CSS-Tricks: css-tricks.com/…
psorensen,

Soluzione interessante lì, ma sembra che stia sostituendo l'intera meta_form()funzione. Ho aggiornato la risposta: la query SQL di base è stata modificata nella versione 4.3 di WP. Vedi questo miglioramento delle prestazioni con questa nuova query SQL rispetto alla nostra post_idrestrizione aggiuntiva ?
birgire,

Risposte:


5

Se vuoi testare il tuo SQL personalizzato per vedere come influisce sul tempo di caricamento, puoi provare questo scambio di query:

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

Qui usiamo il add_meta_boxes_{$post_type}gancio, dove $post_type = 'post'.

Qui scambiamo l'intera query, ma avremmo anche potuto modificarla per supportare il limite dinamico.

Spero che tu possa adattarlo alle tue esigenze.

Aggiornare:

Questa query core SQL potenzialmente lenta, ora è stata modificata nella versione 4.3 di WP

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

per:

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;

Controlla il ticket principale # 24498 per maggiori informazioni.


2

Se sfogli il codice sorgente della funzione troverai questo:

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

Utilizzando l' postmeta_form_keyshook è possibile specificare manualmente le chiavi per evitare di chiamare del tutto questa query inefficiente:

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

Interessante. Dove esiste nel codice sorgente questo?
psorensen,

wp-admin /
Includes

2

Puoi provarlo. Questa non è una soluzione, ma una soluzione temporanea.

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

La rimozione dei metabox impedisce anche la query lenta.

function remove_metaboxes() {
     remove_meta_box( 'postcustom', 'page', 'normal' );
}
add_action('admin_menu', 'remove_metaboxes');
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.