Минимизация запросов к базе данных при использовании расширенных настраиваемых полей


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

  • 'person' - это пользовательский тип сообщения (около 300 человек)
  • 'date_accredited' - это поле даты, добавленное с помощью плагина Расширенных пользовательских полей.

Только аккредитованный персонал будет иметь 'date_accredited'.

Мне нужно перечислить всех 'person', НО со ВСЕМИ аккредитованными сотрудниками перечислены первыми (таким образом, около 20 аккредитованных сотрудников занимают первое место).

В данный момент я делаю вызов WP_Query, например:

$args = array(
    'posts_per_page' => -1, 
    'post_type' => 'people', 
    'no_found_rows' => true, 
    'meta_key' => 'date_accredited'
);
$people = new WP_Query($args);

После этого я делаю:

while($people->have_posts()): $people->the_post();      
    $my_post_meta = get_post_meta($post->ID, 'date_accredited', true);
    if (!empty($my_post_meta)) {
        array_push($accredited, $post);
    } else {
        array_push($notAccredited, $post);
    }
endwhile;

Оставляя нас с двумя массивами объектов "человек". Я думал здесь о том, что я мог бы сделать что-то вроде следующего, чтобы получить список, который я хочу:

foreach($accredited as $person):
    personTile($person);
endforeach;

foreach($notAccredited as $person):
    personTile($person);
endforeach;

Я пытаюсь избежать повторного запроса базы данных.

Функция personTile(); должна была выводить различную информацию и HTML (the_post_thumbnail() и различные Расширенные поля настраиваемых полей), но сейчас я понимаю, что ничего из этого не включено в объекты post, которые я получаю от WP_Query(), поэтому я вынужден использовать такие вещи, как:

  • get_the_post_thumbnail($person->ID)
  • get_permalink($person->ID)
  • get_field('date_accredited', $person->ID)

Все это стоит еще одного запроса к БД (каждый!), и что еще хуже, поскольку они находятся в цикле, каждый из них происходит около 300 раз.

Есть ли какой-либо способ включить поля постоянной ссылки, миниатюры и ACF в исходный запрос БД? Стал бы я нужно прибегнуть к пользовательскому запросу MySQL???

Любые другие предложения приветствуются!

Author: Mike Source, 2015-01-28

1 answers

Все это стоит еще одного запроса к БД (каждый!), и что еще хуже, поскольку они находятся в цикле, каждый из них происходит около 300 раз.

Не паникуйте! Сообщения из вашего запроса хранятся в кэше объектов WordPress (это просто память, если у вас нет специальной системы кэширования).

Все функции, которые работают с сообщениями, проходят через этот кэш, поэтому в вашем случае нет дополнительного попадания в базу данных, даже если вы не находитесь в "цикле".

Ты однако вы захотите вставить эту строку сразу после вашего запроса:

// http://wpseek.com/function/update_post_thumbnail_cache/
update_post_thumbnail_cache( $people );

При этом будут запущены два дополнительных запроса (сообщения и мета-данные сообщений), которые добавят все эскизы (вложения) для сообщений в экземпляре WP_Query в один и тот же кэш.

В противном случае вы получите множество запросов (по два для каждого сообщения с миниатюрой).

N.B: Есть несколько WP_Query аргументов, которые изменят способ кэширования сообщений:

  • update_post_meta_cache (почти всегда да)
  • update_post_term_cache (если вам не нужны термины, вы можете сохранить запрос здесь)
  • fields (если нет all, то ничего не кэшируется и выше игнорируется)
  • cache_results (если значение false, то ничего не кэшируется и все вышеперечисленное игнорируется)
 4
Author: TheDeadMedic, 2015-01-28 14:09:46