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


10

我的帖子有许多自定义的元字段。在帖子中,我会根据需要致电给他们get_post_meta。对于10个meta字段,我正在使用10次。

我做对了吗?意思是,上述方法是否存在任何性能问题,如果是,那么如何减少通话次数。

我知道这里有可用的答案:“ 自定义字段和性能”,它说明了“单个查询”的使用。但这并不清楚,所以请再次询问是否有人知道并想详细分享。

Answers:


25

为了回答这个问题,我已经对此进行了一些测试,结果实际上令人不寒而栗。

这是我的测试

为此,请设置一个测试页面。只需简单地复制page.php,将其重命名并删除循环即可。现在,只需在后端创建一个新页面。开始之前,请先使用空信息测试计时器,以获取没有任何数据的查询量

我为测试帖子共创建了5个meta字段,

  • enclosure
  • First name
  • Last name
  • packages
  • post_views_count

我的测试帖子的ID为530。在帖子内,您只需使用$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>

这给了我以下结果

0.00195秒内有1个查询。

我的第二项测试如下:

<?php               
       timer_start();       

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

令人惊讶地给出了相同的结果

0.00195秒内有1个查询。

如果你看一下源代码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
这称为“交谈”。很棒的答案。
Akhilesh 2014年

1
我很高兴,很高兴为您解决了这个问题。享受:-)
Pieter Goosen 2014年

1
很好 我希望看到针对自定义用户meta的类似测试。
克里斯汀·库珀

1
绝对值得这样做;-)。将在接下来的几天里看到我能做什么,现在要忙几天,@ ChristineCooper
Pieter Goosen

1
真好!请在此线程上用链接标记我,以防您最终这样做!
克里斯汀·库珀

0

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

$meta = get_post_meta( get_the_ID() );

这将获取给定帖子的所有元值。使用该数组,而不是单独获取。


0

正如Pieter Goosen所说,当您首次请求任何元数据时,将缓存一个帖子的所有元数据。

对的任何调用也是如此WP_Query。一旦您致电WP_Query,WordPress 就会在单个查询中获取所有检索到的帖子的元数据。

最坏的情况是您要求get_post_meta输入以前未由WordPress检索的单个帖子ID。在这种情况下,每次调用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个帖子的元数据,这是original的结果WP_Query

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.