自定义帖子元场对帖子性能的影响

时间:2014-10-31 作者:Akhilesh

我有很多自定义元字段的帖子。在帖子中,我根据要求使用get_post_meta. 对于10个元字段,我使用了10次。

我做得对吗?也就是说,上述方法是否存在任何性能问题,如果存在,则如何减少调用次数。

我知道这里有答案:Custom Fields and performance 这就解释了“单一查询”的使用。但这并不清楚,也不合理,所以再次询问是否有人知道并想分享详细信息。

3 个回复
最合适的回答,由SO网友:Pieter Goosen 整理而成

为了回答这个问题,我做了一些测试,结果真的令人兴奋。

这是我自己的测试,为自己设置一个测试页面。只需简单地复制页面即可。php,重命名它并删除循环。现在只需在后端创建一个新页面。开始之前,首先用空信息测试计时器,以获得没有任何数据的查询量

我已经为一个测试帖子创建了5个元字段,

  • enclosure,
  • First name,
  • Last name,
  • packagespost_views_count530. 在一个帖子里,你可以简单地使用$post->IDget_the_ID() 设置帖子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秒。

    如果你看看source code 对于get_post_meta(), 你会看到的get_post_meta() 只是一个包装get_metadata(). 所以这是你需要看的。这个source code 对于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>";
    
    将显示

    汤姆·斯托姆

SO网友:Nilambar Sharma

您可以使用get_post_meta 一次获取所有元字段值。

$meta = get_post_meta( get_the_ID() );
这将获取给定帖子的所有元值。使用该数组,而不是单独获取。

SO网友:greenone83

正如PieterGoosen所说,当您第一次请求任何元数据时,一篇文章的所有元数据都会被缓存。

对于任何调用WP_Query. 你一打电话WP_Query, WordPress在一个查询中获取所有检索到的帖子的元数据。

最坏的情况是你打电话get_post_meta 用于WordPress之前未检索到的单个帖子ID。在这种情况下,每次调用get_post_meta 将生成一个查询。

从查询到的示例跟踪wp_postmeta 内部aWP_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.

结束

相关推荐

列出分类法:如果分类法没有POST,就不要列出分类法--取决于定制的POST-META?

这可能很难解释,我不知道是否有解决办法!?我有一个名为“wr\\u event”的自定义帖子类型和一个名为“event\\u type”的分层自定义分类法。自定义帖子类型有一个元框,用于event_date 并且与此帖子类型关联的所有帖子都按以下方式排序event_date. 我在循环中有一个特殊的条件来查询event_date 已经发生了-在这种情况下,它没有显示,但只列在我的档案中。就像你可以使用wp_list_categories() 我编写了一个自定义函数,它以完全相同的方式列出所有分类术语。现在