Як оптимізувати WP-сайт для мільйонів публікацій


19

Я працюю над веб-сайтом для компанії, яка, швидше за все, створює мільйони публікацій за допомогою спеціального типу публікацій. Це молитви, тому в основному користувач на передньому кінці просто надсилає коротку фразу через форму. Про компанію дбає лише вміст публікації та дата публікації. Сайт ще навіть не запустився, і вони вже мають понад 120 000 публікацій, тому я мертвий серйозно, коли кажу мільйони.

Отже, пара питань оптимізації:

  1. Скажімо, у мене є категорія "показана" у користувацькому типі публікацій, який містить 500 000 публікацій. Рекомендована категорія містить лише 500 публікацій. Якщо я створюю запит для популярних публікацій, я запитую цілих 500 000 публікацій чи лише 500 ознайомлених? Що робити, якщо я хочу лише відобразити десять останніх публікацій?
  2. Під час збереження цього користувальницького типу публікації в базі даних я можу зробити, щоб скоротити ресурси сервера, тим більше, що єдине, що дійсно потрібно - це вміст публікації та дата?
  3. Чи потрібно мені навіть користуватися типом публікації? Мені це в принципі подобається, тому що він добре інтегрований у адміністратора WordPress, але якщо є значні недоліки у роботі, то, напевно, я можу зробити щось інше.

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


Важливо звести до мінімуму запити до бази даних у ваших функціях WordPress та сценарії викликів, але значна частина оптимізації пов'язана з налаштуванням та налаштуванням сервера. Для цього виконайте пошук у мережі серверних помилок. serverfault.com/search?q=optimize+wordpress
iyrin

@RyanLoremIpsum - дякую за коментар, але я сподівався на відповіді на мої конкретні запитання. Більшість того, що я там знайшов, стосується самого сервера, а не того, як працює WordPress та як оптимізувати його з точки зору коду
Jeremiah Prummer

Відповіді:


26

1. Встановіть запит перед запуском WP_Query

Здається, це є найважливішим, що слід пам’ятати, намагаючись звести запити до бази даних до мінімуму, оскільки єдиною можливістю зміни запиту є, звичайно, перед його запуском у базі даних SQL.

Нормальні запити
Для нормального запиту WordPress використовує wp()функцію, яка в свою чергу викликає $wp->main( $query_vars ). Змінні "is_ змінні" з умовних тегів встановлюються перед тим, як передавати їх WP_Query->get_posts(), що перетворює його в запит бази даних MySQL і, нарешті, зберігає їх в об'єкт $ wp_query. Можна фільтрувати запит до того, як він фактично запускається в базі даних SQL .

pre_get_postsДія перехоплює в цей процес, що дозволяє змінити запит , перш ніж він передається WP_Query->get_posts().

Наприклад, якщо ви хочете відфільтрувати запит на публікації в категорії "показаний", ви використовуєте add_action( 'pre_get_posts', 'your_function_name' );і включаєте in_categoryумовний тег всередині your_function_name.

function your_function_name( $query ) {
    if ( $query->in_category( 'featured' ) && $query->is_main_query() ) {
        // Replace 123 with the category ID of the featured category.
        $query->set( 'cat', '123' );
    }
}
add_action( 'pre_get_posts', 'your_function_name' );

Див. Додаток API / Довідка про дії / попередньо отримуйте повідомлення «WordPress Codex

Запити
на сторінку Що стосується шаблонів сторінок, таких як сторінка архіву для категорії "показаний", умовні теги не працюватимуть з pre_get_postsфільтра. Наприклад, ви не можете використовувати is_categoryдля перевірки сторінки архіву, оскільки WP_Query не запущений.

Натомість вам доведеться змінити основний запит на запити сторінок, new WP_Queryякий би виглядав приблизно так $query = new WP_Query( 'cat=123' );. Це запускає запит з відповідним аргументом, встановленим з самого початку.

Див. Довідковий клас / WP-запит «WordPress Codex

2. Збереження в базі даних

Ви можете використовувати фільтр, wp_insert_post_dataгарантуючи, що до нього повертаються лише дані $, що відповідають вашому користувальницькому типу публікації wp_insert_post. Обов’язково додайте умовну заяву, щоб перевірити, чи є ваш власний тип публікації.
API Plugin / Довідник фільтра / wp вставити дані про пост «WordPress Codex

Цей гачок викликається wp_insert_postфункцією, яка викликається wp_update_post під час оновлення власного типу публікації, зазвичай, зберігаючи чернетку або публікуючи публікацію.

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

3. Чи впливають спеціальні типи публікацій на ефективність роботи?

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

Раніше виникла проблема продуктивності, пов’язана зі структурою постійної посилання, змушуючи її звернутися, коли вона починається з тексту замість числа. 3 Це було особливо клопітно для сайтів, на яких розміщено велику кількість сторінок, але це було вирішено з часів WordPress версії 3.3.

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

Інші параметри продуктивності

Перехідні процеси
Це не заміна для зведення запитів до мінімуму у вашому коді, але ви можете використовувати set_transient для зберігання запитів протягом певного часу, щоб нові запити не потрібні. Ось приклад, використаний у публікації Дейва Клементса . Також зауважте, що він рекомендує додати save_postдію для видалення перехідного періоду кожного разу, коли заданий тип публікації оновлюється.

<?php // IN THE SPOTLIGHT QUERY
if( false === ( $its_query = get_transient( 'its_query' ) ) ) {
    $pttimestamp = time() + get_option('gmt_offset') * 60*60;
    $its_query = new WP_Query( array(
        'post_type' => 'spotlight',
        'posts_per_page' => 1,
            'post__not_in' => $do_not_duplicate,
        'meta_query' => array(
            array(
                'key' => '_hpc_spotlight_end_time',
                'value' => $pttimestamp,
                'compare' => '>'
            )
        )
    ) );
    set_transient( 'its_query', $its_query, 60*60*4 );
}
if( have_posts() ) { // HIDE SECTION IF NO CURRENT ITS FEATURE ?>
    // LOOP GOES HERE: NOT IMPORTANT TO EXAMPLE
<?php } ?>

Більш детальна оптимізація запитів
Томас Гріффін має кілька хороших порад у своєму підручнику з оптимізації запитів WordPress . Ось короткий список його пропозицій:

  • Встановіть 'cache_results' => falseодноразові запити, якщо ваш сервер не використовує стійке кешування, наприклад Memcached. Одноразові запити описуються як "запити, які використовуються для показу невеликої кількості даних. Можливо, ви просто хочете відображати пов'язані заголовки публікацій, пов’язані з поточною публікацією, або ви можете відображати спадне повідомлення, яке потрібно вибрати для певний параметр налаштування. "

    Його приклад: $query = get_posts( array( 'posts_per_page' => 1, 'cache_results' => false ) );

  • Встановіть, 'no_found_rows' => trueде не потрібна сторінка. Це дозволить "обійти підрахунок результатів MySQL, щоб побачити, чи потрібна нам сторінка чи ні".

    Його приклад: $query = new WP_Query( array( 'posts_per_page' => 1, 'no_found_rows' => true ) );

  • Запит для поштових ідентифікаторів тільки якщо це все , що вам потрібно 'fields' => 'ids' в get_posts. Це повинно значно зменшити обсяг даних, що повертаються, що досить багато за повідомлення, якщо подивитися Опис бази даних «WordPress Codex

    Його приклад: $query = get_posts( array( 'posts_per_page' => 1, 'fields' => 'ids' ) );

На додаток до останньої підказки, те ж міркування можна застосувати, коли вам потрібно лише одне або кілька полів публікації, використовуючи get_post_field .

Суттєве розуміння того, як працює запит, є надзвичайно важливим. Чим конкретніше ви можете бути зі своїми запитами, тим менше роботи будете вимагати від вашої бази даних SQL. Це означає, що існує велика кількість можливостей для управління запитами до бази даних. Будьте уважні до користувацьких запитів щодо того, куди вони запущені (чи це сторінка адміністратора?), Використовуйте належну санітарію в прямих запитах і намагайтеся використовувати нативні функції WordPress там, де це дозволяє досягти такої ж продуктивності.


2
Відмінна та надзвичайно корисна відповідь, дякую!
Єремія Прюммер

Тема повністю побудована на замовлення, тому ми буквально лише запитуємо абсолютно необхідні елементи. Вони надзвичайно корисні, хоча. Враховуючи це, я збираюся повернутися назад і внести деякі зміни у свої запити. ;)
Єремія Прюммер

1
Я б додав, що вам слід уникати мета-запитів, де це можливо. Звичайно, не запускайте запит проти двох метаполів одночасно. Це призводить до подвійних і потрійних запитів, які швидко перетворюються на нігтьма продуктивності. Спеціальні типи публікацій часто можуть допомогти у цьому.
Чарльз Хаймет

3

Я також додаю:

    'no_found_rows'          => true,
    'update_post_term_cache' => false,
    'update_post_meta_cache' => false,
    'cache_results'          => false
  • no_found_rows (boolean) - зробіть це справжнім, коли вам не потрібна сторінка та не потрібно рахувати загальну кількість знайдених публікацій.
  • cache_results (boolean) - Кеш інформації інформації.
  • update_post_meta_cache (boolean) - Опублікувати кеш-інформаційний кеш.
  • update_post_term_cache (булева) - кеш інформації інформації про термін.

Використовуючи ці параметри і передаючи значення як FALSE, ми можемо зробити запит швидше, зупинивши виконання додаткових запитів до бази даних.

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

Відвідайте: https://drujoopress.wordpress.com/2013/06/27/how-to-optimize-wordpress-query-to-get-results-faster/#more-184


1
Будь ласка , змініть свій відповідь , і додати пояснення: чому це може вирішити цю проблему?
фуксія

Я не можу додати коментар до цієї відповіді: wordpress.stackexchange.com/a/166699/57674
rigosan

1

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

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

Можливо, ви хочете оптимізувати, як зберігаються метадані (наприклад, не зберігати дані, пов’язані з ping), але такий спосіб залежить від того, що саме ви робите, і врешті-решт, вам може знадобитися більш міцний процесор, тому, можливо, не варто ваших проблем .

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