I have the posts which have many custom defined meta fields. On posts I am calling them on requirement using get_post_meta. Means for 10 meta fields I am using it 10 times.

Am I doing it right? Means, is there any performance issue with the above method and if yes then how to reduce the number of calls.

I am aware of the answer available here: Custom Fields and performance which explains that the use of 'single query'. But it is not clear and sound so asking again if somebody knows and want to share in detail.

up vote 19 down vote accepted

To answer this, I have gone and done some tests on this, and the results was actually mind blowing.

Here is my test

To this yourself, set yourself up with a test page. Just simply copy page.php, rename it and delete the loop. Now just create a new page in the back end. Before you start, first test your timer with empty info to get the amount of queries without any data

I have created 5 meta fields altogether for a test post,

  • enclosure,
  • First name,
  • Last name,
  • packages and
  • post_views_count

My test post had an ID of 530. Inside a post you can just simply use $post->ID or get_the_ID() to set the post ID

So my first test was as follows:

<?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>

which gave me the following results

1 queries in 0.00195 seconds.

My second test was as follows:

<?php               
       timer_start();       

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

which, surprisingly gave the same result

1 queries in 0.00195 seconds.

If you look at the source code for get_post_meta(), you'll see that get_post_meta() is simply just a wrapper for get_metadata(). So this is were you need to look. The source code for get_metadata(), you'll see that the metadata get cached.

So on your question about which to use and about performance, the answer will be, it is up to you. You have seen the proof in the results

In my personal opinion, if you need to retrieve 10 meta data fields, (or in my case 5), use the second approach in my answer.

$a = get_post_meta(530);

It is not only quicker to write, but you should also not repeat code. Another point to note here, the second approach holds all meta fields in an array which can be very easily accessed and retrieved

Just as matter of example, here is my output from $a if I do 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"
  }
}

You can now access any of the returned meta data in your post as follows:

echo $a['First name'][0] . " " . $a['Last name'][0] . "<br>";

Which will display

Tom Storm

  • 3
    This is called as 'Walk the Talk'. Wonderful answer. – Akhilesh Nov 1 '14 at 13:57
  • 1
    My pleasure, glad it worked out for you. Enjoy :-) – Pieter Goosen Nov 1 '14 at 14:36
  • 1
    This is very nice. I would love to see a similar test focusing on custom user meta's instead. – Christine Cooper Jul 22 '15 at 18:09
  • 1
    Definitely worth doing it ;-). Will see what I can do in the next few days, have a hectic couple of days ahead now @ChristineCooper – Pieter Goosen Jul 22 '15 at 18:14
  • 1
    Nice! Please tag me on this thread with a link in case you end up doing it! – Christine Cooper Jul 22 '15 at 18:20

You can use get_post_meta to fetch all meta field values at once.

$meta = get_post_meta( get_the_ID() );

This will fetch all meta values of the given post. Use that array instead of fetching individually.

As Pieter Goosen stated, all the meta data for one post is cached when you request any meta-data for the first time.

This is also true for any calls to WP_Query. As soon as you call WP_Query, WordPress fetches the meta data for all retrieved posts in a single query.

The worst case scenario is that you call get_post_meta for individual post IDs which have not been retrieved by WordPress before. In this case, each call to get_post_meta will result in a single query.

A sample trace from a query to wp_postmeta inside a 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)

As you can see, the call originates from within get_posts and retrieves meta data for 2 posts, which is the result of the original WP_Query.

Your Answer

 
discard

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.