Влияние пользовательского мета-поля на производительность записи


10

У меня есть сообщения, которые имеют много пользовательских мета-полей. На сообщениях я звоню им по требованию используя get_post_meta. Значит для 10 метаполей я использую его 10 раз.

Я делаю это правильно? Значит, есть ли проблемы с производительностью вышеупомянутым методом и если да, то как уменьшить количество вызовов.

Мне известен ответ, доступный здесь: пользовательские поля и производительность, что объясняет использование «одного запроса». Но это не ясно и звучит, поэтому спрашиваю еще раз, если кто-то знает и хочет поделиться в деталях.

Ответы:


25

Чтобы ответить на это, я пошел и сделал несколько тестов по этому вопросу, и результаты на самом деле было ошеломляющим.

Вот мой тест

Для этого сами создайте себе тестовую страницу. Просто скопируйте page.php, переименуйте его и удалите цикл. Теперь просто создайте новую страницу в конце. Прежде чем начать, сначала проверьте ваш таймер с пустой информацией, чтобы получить количество запросов без каких-либо данных

Я создал 5 мета-полей для тестового поста,

  • enclosure,
  • First name,
  • Last name,
  • packages и
  • post_views_count

Мой тестовый пост имел идентификационный номер 530. Внутри сообщения вы можете просто использовать $post->IDили get_the_ID()установить идентификатор сообщения

Итак, мой первый тест был следующим:

<?php               
       timer_start();       

       $a = get_post_meta(530, 'enclosure', true);
       $b = get_post_meta(530, 'First name', true);
       $c = get_post_meta(530, 'Last name', true);
       $d = get_post_meta(530, 'packages', true);
       $e = get_post_meta(530, 'post_views_count', true);
?>
<p><?php echo get_num_queries(); ?> queries in <?php timer_stop(1, 5); ?> seconds. </p>

который дал мне следующие результаты

1 запрос за 0.00195 секунд.

Мой второй тест был следующим:

<?php               
       timer_start();       

       $a = get_post_meta(530);
?>
<p><?php echo get_num_queries(); ?> queries in <?php timer_stop(1, 5); ?> seconds. </p>

что неожиданно дало тот же результат

1 запрос за 0.00195 секунд.

Если вы посмотрите на исходный код для get_post_meta(), вы увидите, что get_post_meta()это просто оболочка для get_metadata(). Так что это, где вы должны посмотреть. Исходный код для get_metadata(), вы увидите , что метаданные кэшироваться.

Так что на ваш вопрос о том, что использовать и о производительности, ответ будет, это зависит от вас. Вы видели доказательство в результатах

По моему личному мнению, если вам нужно получить 10 полей метаданных (или в моем случае 5), используйте второй подход в моем ответе.

$a = get_post_meta(530);

Это не только быстрее писать, но вы также не должны повторять код. Еще один момент, на который следует обратить внимание: второй подход содержит все мета-поля в массиве, к которым очень легко получить доступ и получить

Как пример, вот мой вывод, $aесли я сделаюvar_dump( $a );

array(9) {
  ["_edit_lock"]=>
  array(1) {
    [0]=>
    string(12) "1414838328:1"
  }
  ["_edit_last"]=>
  array(1) {
    [0]=>
    string(1) "1"
  }
  ["_custom_sidebar_per_page"]=>
  array(1) {
    [0]=>
    string(7) "default"
  }
  ["post_views_count"]=>
  array(1) {
    [0]=>
    string(1) "0"
  }
  ["packages"]=>
  array(1) {
    [0]=>
    string(1) "0"
  }
  ["repeatable_names"]=>
  array(1) {
    [0]=>
    string(79) "a:1:{i:0;a:3:{s:4:"role";s:4:"fool";s:4:"name";s:6:"Pieter";s:3:"url";s:0:"";}}"
  }
  ["enclosure"]=>
  array(1) {
    [0]=>
    string(105) "http://localhost/wordpress/wp-content/uploads/2014/09/Nissan-Navara-Tough-City.avi
13218974
video/avi
"
  }
  ["First name"]=>
  array(1) {
    [0]=>
    string(3) "Tom"
  }
  ["Last name"]=>
  array(1) {
    [0]=>
    string(5) "Storm"
  }
}

Теперь вы можете получить доступ к любым возвращенным метаданным в вашем сообщении следующим образом:

echo $a['First name'][0] . " " . $a['Last name'][0] . "<br>";

Который будет отображать

Том Сторм


4
Это называется «иди на разговор». Прекрасный ответ.
Ахилеш

1
Мое удовольствие, рад, что это сработало для вас. Наслаждайтесь :-)
Питер Гусен

1
Это очень мило. Мне бы хотелось, чтобы подобный тест был сфокусирован на пользовательских пользовательских мета-версиях.
Кристина Купер

1
Определенно стоит сделать это ;-). Посмотрим, что я смогу сделать в ближайшие несколько дней, у меня будет беспокойная пара дней вперед @ChristineCooper
Питер Гусен

1
Приятно! Пожалуйста, отметьте меня в этой теме со ссылкой на случай, если вы в конечном итоге сделаете это!
Кристина Купер

0

Вы можете использовать, get_post_metaчтобы получить все значения метаполя одновременно.

$meta = get_post_meta( get_the_ID() );

Это извлечет все мета значения данного поста. Используйте этот массив вместо выборки по отдельности.


0

Как заявил Питер Гусен, все метаданные для одного поста кэшируются при первом запросе метаданных.

Это также верно для любых звонков WP_Query. Как только вы позвоните WP_Query, WordPress извлекает метаданные для всех полученных сообщений в одном запросе.

В худшем случае вы вызываете get_post_metaотдельные идентификаторы постов, которые не были извлечены WordPress ранее. В этом случае каждый вызов get_post_metaприведет к одному запросу.

Образец след от запроса к wp_postmetaвнутри WP_Query:

SELECT post_id, meta_key, meta_value 
    FROM wp_postmeta 
    WHERE post_id IN (491,347) 
    ORDER BY meta_id ASC

#0 /wp-includes/wp-db.php(1567): wpdb->_do_query('SELECT post_id,...')
#1 /wp-includes/wp-db.php(1958): wpdb->query('SELECT post_id,...')
#2 /wp-includes/meta.php(814): wpdb->get_results('SELECT post_id,...', 'ARRAY_A')
#3 /wp-includes/post.php(5546): update_meta_cache('post', Array)
#4 /wp-includes/post.php(5529): update_postmeta_cache(Array)
#5 /wp-includes/query.php(3614): update_post_caches(Array, 'post', true, true)
#6 /wp-includes/query.php(3836): WP_Query->get_posts()
#7 /wp-includes/query.php(3946): WP_Query->query(Array)
#8 /wp-content/plugins/***/***.php(134): WP_Query->__construct(Array)

Как видите, вызов происходит изнутри get_postsи извлекает метаданные для 2 сообщений, что является результатом оригинала WP_Query.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.