在大多数情况下,$wpdb->GET_RESULTS比WP_QUERY快,这是真的吗?

时间:2014-06-26 作者:WPRookie82

在我的主页上,我有一个部分,我必须显示最后五篇特色文章,其中特色文章只是一篇带有自定义字段is\\u 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 个回复
最合适的回答,由SO网友:gmazzap 整理而成

如何准备()我的wpdb查询?我尝试了,但由于第二个参数的原因,无法管理。

这个prepare() 工程解释见Codex, 您需要一个带有占位符和其他参数的查询来替换占位符。如果没有占位符(因此查询中没有可变部分),则可以使用esc_sql 避免SQL注入,但这只有在使用用户输入构建查询时才有意义。OP中的查询是完全硬编码的,因此不需要prepare() 也不是esc_sql().

在使用prepare之后,我是否正确地假设在安全性和性能方面,wpdb确实是一个更好的解决方案?

简短回答:no. WP_Query 只是一种更高级别的查询方法,它构建一个查询字符串,然后使用$wpdb 在数据库中运行该sql查询。

如果查看OP中的两个查询,它们是不同的,例如,使用$wpdb 不考虑发布状态、发布日期或发布密码,因此,如果您已删除、计划或私人发布,则使用第一个查询将它们显示给用户。此外,查询不考虑结果排序和其他内容。当然,您可以构建一个考虑所有内容的复杂查询字符串,然后使用$wpdb, 您有两种可能性:

每当您需要循环时,都要编写一个复杂的硬编码查询字符串:这真的很难处理,而且容易出错。请编写一些以灵活方式处理查询的代码:这将非常困难,您应该编写很多已经由core在中处理的代码WP_Query: 这毫无意义WP_Query 火灾很多filter and action hooks, 成千上万的插件和主题依赖于它们:通过运行手册$wpdb 查询循环会破坏很多东西。

因此,如果需要查询帖子,请使用WP_Query: 几毫秒不值得数小时的代码和挫折。使用$wpdb 仅当您需要执行核心不处理的查询时。

值得添加@TomJNowell 此处评论:

还应记住:WP_Query 将允许您利用WordPress保留的大量内部缓存,例如在第二次查询时检索一次帖子等。如果您有5万篇帖子要一次全部查询,您可能应该使用作业队列或CLI脚本来完成您的工作(除非您只有数十个用户和大量资金用于服务器)

结束

相关推荐

wordpress admin security

我用不同的工具扫描我的网站,但它没有显示恶意脚本。但当我在管理仪表板中看到时,我在body标签下面看到了奇怪的方形符号。我试图检查管理索引文件,根索引文件,但什么都没有。有人放了这个脚本。而且,当我试图采取备份它不允许我采取。使用BackupFordPress插件。然而,所有其他的事情都在运行,但在管理方面仍然存在一些问题。如何检测和删除此项。