Правда ли, что $wpdb->получение результатов в большинстве случаев быстрее, чем запрос WP?
На моей домашней странице у меня есть раздел, в котором я должен отобразить последние пять избранных сообщений, где избранное сообщение - это просто сообщение с настраиваемым полем is_featured, равным 1.
Я добился того, чего хотел, с помощью двух разных типов кодов:
Использование базы данных wpdb
<?php
$featuredPosts = $wpdb->get_results("
SELECT ID, post_title FROM $wpdb->posts
LEFT JOIN $wpdb->postmeta ON($wpdb->posts.ID = $wpdb->postmeta.post_id)
WHERE $wpdb->postmeta.meta_key = 'is_featured'
ORDER BY ID DESC LIMIT 5
");
if ($featuredPosts)
{
$htmlOutput = '';
foreach ($featuredPosts as $featPost)
$htmlOutput .= '<br /><a href="'.get_permalink($featPost->ID).'">'.$featPost->post_title.'</a>';
}
echo $htmlOutput;
?>
Согласно плагину "Монитор запросов", этот запрос занимает 0,1 секунды и генерирует следующий SQL:
SELECT ID, post_title
FROM wp_posts LEFT JOIN wp_postmeta ON(wp_posts.ID = wp_postmeta.post_id)
WHERE wp_postmeta.meta_key = 'is_featured'
ORDER BY ID DESC
LIMIT 5
Использование родного Wordpress звонки
<?php
$featuredPostsRevised = new WP_Query
(
array
(
'meta_query' => array
(
array
(
'key' => 'is_featured'
)
)
)
);
while($featuredPostsRevised->have_posts()) : $featuredPostsRevised->the_post();
?>
<br />
<a href="<?php the_permalink(); ?>" title="<?php the_title_attribute(); ?>"><?php the_title(); ?></a>
<?php
endwhile;
?>
Согласно плагину "Монитор запросов", этот запрос занимает 0,2 секунды и генерирует несколько более длинный SQL:
SELECT SQL_CALC_FOUND_ROWS wp_posts.ID
FROM wp_posts
INNER JOIN wp_postmeta
ON (wp_posts.ID = wp_postmeta.post_id)
WHERE 1=1
AND wp_posts.post_type = 'post'
AND (wp_posts.post_status = 'publish'
OR wp_posts.post_status = 'private')
AND (wp_postmeta.meta_key = 'is_featured' )
GROUP BY wp_posts.ID
ORDER BY wp_posts.post_date DESC
LIMIT 0, 10
Мои вопросы таковы:
Как я могу
prepare()
выполнить свойwpdb
запрос? Я пытался, но не смог справиться из-за второго параметра.После использования prepare я прав, предполагая, что с точки зрения безопасности и производительности
wpdb
действительно является лучшим решением?
1 answers
Как я могу подготовить() свой запрос wpdb? Я пытался, но не смог справиться из -за второго параметра.
Работа prepare()
описана в Кодексе, вам нужен запрос с заполнителями и дополнительными аргументами для замены этих заполнителей. Если у вас нет заполнителей (поэтому в запросе нет переменных частей), вы можете использовать esc_sql, чтобы избежать SQL-инъекций, но это имеет смысл только тогда, когда запрос построен с использованием пользовательского ввода.
Запрос в OP, полностью жестко закодирован, поэтому нет необходимости ни prepare()
, ни esc_sql()
.
После использования prepare я прав, предполагая, что с точки зрения безопасности и производительности wpdb действительно является лучшим решением?
Короткий ответ: нет. WP_Query
- это просто подход к запросам более высокого уровня, он создает строку запроса, а затем использует $wpdb
для выполнения этого sql-запроса в базе данных.
Если вы посмотрите на 2 запроса в OP, то они разные, например, запрос выполнялся использование $wpdb
не учитывает статус публикации, дату публикации или пароль для публикации, поэтому, если вы удалили, запланировали или закрыли публикации, с помощью первого запроса они будут показаны пользователям.
Также в запросе не учитывается порядок результатов и некоторые другие вещи.
Конечно, вы можете создать сложную строку запроса, которая учитывает все, а затем запустить ее с помощью $wpdb
, у вас есть две возможности:
- пишите сложную жестко закодированную строку запроса каждый раз, когда вам нужен цикл: это действительно подавляющий и подверженный ошибкам
- напишите некоторый код, который обрабатывает запрос гибким способом: это будет очень сложно, и вы должны написать много кода, который уже обрабатывается ядром в
WP_Query
: это не имеет смысла.
Есть еще один важный фактор, который следует учитывать: WP_Query
срабатывает довольно много фильтров и крючков действий , и тысячи плагинов и тем полагаются на них: запустив руководство $wpdb
запрашивая циклы, вы сломаете много вещей.
Итак, если вам нужно запросить сообщения использовать WP_Query
: несколько миллисекунд не стоят многих часов кода и разочарований. Используйте $wpdb
только тогда, когда вам нужно выполнять запросы, не обрабатываемые ядром.
Стоит добавить @Tomjnowell Комментарий здесь:
Также следует иметь в виду, что WP_Query
позволит вам воспользоваться множеством внутренних кэшей, хранящихся в WordPress, таких как получение сообщения один раз, если оно запрашивается во второй раз и т. Д. Если у вас есть 50 тысяч сообщений для запроса все сразу, вы, вероятно, должны использовать очередь заданий или сценарий командной строки для выполнения своей работы (если только у вас нет только десятков пользователей и много денег, которые можно потратить на сервере)