Admin: halaman edit yang sangat lambat disebabkan oleh permintaan meta inti

11

Kami telah memperhatikan waktu muat yang sangat lama ketika akan mengedit posting atau halaman. Menggunakan Query Monitor, kami menemukan bahwa kueri inti WP ini meningkat hingga 15-20-an.

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

Kami menggunakan banyak postmeta karena salah satu dari jenis postingan kami menggunakan sekitar 20 atau lebih bidang khusus. Saya akan mengatakan mungkin kita terlalu mengandalkan postmeta, tapi ini sepertinya permintaan yang sangat tidak efisien, melihat bahwa itu bahkan tidak memilih ID posting.

Apakah ini masalah umum? Apakah ada cara untuk menonaktifkan fungsi ini melalui filter? Terima kasih atas masukannya.

psorensen
sumber
Apakah ini terjadi tanpa plugin dan tema default?
birgire
Ya itu. Seperti yang disebutkan di atas, saya telah mengidentifikasi permintaan lambat sebagai milik WP core. Dengan fungsi dalam jawaban yang saya berikan, kotak meta bidang khusus dinonaktifkan, yang mencegah kueri berjalan.
psorensen
2
Saya tahu, saya baru saja memeriksa meta_form()fungsinya dan ini memang query SQL yang dihasilkan dari fungsi inti itu. Anda dapat mencoba menambahkan metabox khusus Anda sendiri dengan modifikasi pada kode meta_form()dan menggunakan di sana SQL query yang Anda sarankan. Saya menemukan tiket trac tertutup # 8561 ini . Anda mungkin dapat membuat tiket lain atau mencoba untuk membuka kembali tiket ini? PS: Perhatikan bahwa halaman induk yang memilih metabox juga bermasalah. Jika Anda mendapat 1 juta halaman, maka semuanya akan muncul sebagai opsi pilih!
birgire
2
Sebuah solusi yang diajukan pada CSS-Tricks: css-tricks.com/…
psorensen
Solusi menarik di sana, tetapi sepertinya itu menggantikan seluruh meta_form()fungsi. Saya memperbarui jawabannya - kueri inti SQL telah disesuaikan di WP versi 4.3 .. Apakah Anda melihat peningkatan kinerja dengan kueri SQL baru ini dibandingkan dengan post_idbatasan tambahan kami ?
birgire

Jawaban:

5

Jika Anda ingin menguji SQL khusus Anda untuk melihat bagaimana hal itu mempengaruhi waktu pemuatan, Anda dapat mencoba bertukar kueri ini:

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

Di sini kita menggunakan add_meta_boxes_{$post_type}pengait, di mana $post_type = 'post'.

Di sini kami menukar seluruh permintaan, tetapi kami juga bisa menyesuaikannya untuk mendukung batas dinamis.

Semoga Anda dapat menyesuaikan ini dengan kebutuhan Anda.

Memperbarui:

Permintaan SQL inti yang berpotensi lambat ini, kini telah disesuaikan di WP versi 4.3 dari

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

untuk:

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;

Lihatlah tiket inti # 24498 untuk info lebih lanjut.

birgire
sumber
2

Jika Anda menelusuri kode sumber fungsi Anda akan menemukan ini:

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

Dengan menggunakan postmeta_form_keyspengait, Anda dapat menentukan kunci secara manual untuk menghindari memanggil kueri yang tidak efisien ini sama sekali:

add_filter('postmeta_form_keys', function(){
    return ['your_meta_key'];
});
Dan K.
sumber
Menarik. Di mana dalam kode sumber apakah ini ada?
psorensen
wp-admin / include / template.php: 595 pada 4.4
markdwhite
2

Bisakah Anda mencoba ini? Ini bukan solusi, tetapi solusi sementara.

// 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 );
prosti
sumber
-1

Menghapus metabox juga mencegah permintaan lambat.

function remove_metaboxes() {
     remove_meta_box( 'postcustom', 'page', 'normal' );
}
add_action('admin_menu', 'remove_metaboxes');
psorensen
sumber