Адміністратор: дуже повільна сторінка редагування, викликана основним мета-запитом


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

Ми використовуємо багато постмета, оскільки один із типів публікацій використовує приблизно 20 або більше спеціальних полів. Я б сказав, можливо, ми занадто багато покладаємось на постмета, але це здається дуже неефективним запитом, бачачи, що це навіть не вибір ідентифікатора посади.

Це поширене питання? Чи є спосіб відключити цю функцію через фільтр? Дякуємо за будь-який вклад.


Це відбувається без плагінів і теми за замовчуванням?
birgire

Так. Як було сказано вище, я визначив повільний запит як належність до ядра WP. За допомогою функції у відповіді, яку я надав, мета-поле спеціальних полів вимкнено, що запобігає запуску запиту.
псоренсен

2
Я бачу це, я щойно перевірив meta_form()функцію, і це справді генерований SQL-запит з цієї основної функції. Ви можете спробувати додати свій власний метабокс із модифікаціями до коду meta_form()та використати запропонований SQL-запит. Я знайшов цей номер # 8561 закритого квитка. Ви можете створити інший квиток або спробувати відкрити цей квиток? PS: Зауважте, що вибір батьківської сторінки метабокс також є проблематичним. Якщо у вас є 1 мільйон сторінок, то всі вони відображатимуться як опції вибору!
birgire

2
Рішення, запропоноване на CSS-Tricks: css-tricks.com/…
psorensen

Цікаве рішення є, але схоже, що воно замінює всю meta_form()функцію. Я оновив відповідь - основний запит SQL був скоригований у версії 4.3 версії WP. Чи бачите ви якийсь приріст продуктивності за допомогою цього нового запиту SQL порівняно з нашим додатковим post_idобмеженням?
birgire

Відповіді:


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'];
});

Цікаво. Де у вихідному коді це існує?
псоренсен

wp-admin /
include

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');
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.