4

I am working on the design of a blog with the below(just a sample) category hierarchy.

                                          PARENT
                                             |
                     |------------------------------------------------|
                   Food                                           Fashion
                     |                                                |
          |---------------------|                       |---------------------|
      European                Asian                  European               Asian
          |                     |                       |                     |
    |---------|           |-----------|             |--------|           |--------|
Italian    French      Chinese    Japanese       Italian  French     Chinese   Japanese

On the homepage, my client wants to display the three last posts of all the level 4 children, hence:

  • The last three posts of Parent>Food>European>Italian
  • The last three posts of Parent>Food>European>French
  • The last three posts of Parent>Food>Asian>Chinese, etc.
  • etc.

My first attempt was like this:

$allPosts = new WP_Query('cat=20, 21, 24, 22, 23, 25, 75, 84, 79, 85, 83, 96, 95, 97, 65, 68, 107, 48, 49&showposts=100&order=ASC');

According to a debugging plugin, 18 queries were called on the page but I realised that such a call makes no sense for what I want because if a category has 2000 posts, the 100 posts this line will retrieve will all be from the same category.

I therefore split the calls, like this:

$italianFood = new WP_Query('cat=20&showposts=3&order=DESC');
$italianFashion = new WP_Query('cat=21&showposts=3&order=DESC');
$frenchFood = new WP_Query('cat=24&showposts=3&order=DESC');
$frenchFashion = new WP_Query('cat=22&showposts=3&order=DESC');

This works but after calling ALL categories, the number of query calls to the database went up to 260!

I will cache the page with a plugin, but do I really have to fire 260+ DB calls to achieve what I want?

3
  • In the meantime, I tried "get_posts" instead of "WP_Query" as in get_posts("post_type=post&numberposts=3&category=20) which apparently reduced the number of calls from 260 to 220.
    – WPRookie82
    Jul 20, 2014 at 11:39
  • 260 seems high, had you tried dumping the list of calls and narrowing down what exactly blows it up? get_posts()/WP_Query are nearly identical (former wraps latter) btw.
    – Rarst
    Jul 20, 2014 at 11:45
  • I have 19 countries, all of which are divided in Food and Fashion so a total of 38 Level-4 categories and hence a total of 38 WP_Query (or get_posts) calls. It seems for every post, the page is calling wp_posts, wp_terms and wp_postmeta, albeit joined for posts in the same category : WHERE ID IN (1208,1207,1206);
    – WPRookie82
    Jul 20, 2014 at 11:50

1 Answer 1

2

You could just write your own query, too. That way, it's one query per category:

global $wpdb;

$query = '
SELECT wpp1.*
FROM ' . $wpdb->posts . ' AS wpp1
LEFT JOIN ' . $wpdb->term_relationships . ' AS wptr1 ON wptr1.object_id = wpp1.ID
WHERE post_type = %s
AND post_status = %s
AND wptr1.term_taxonomy_id = %d
ORDER BY wpp1.post_date DESC
LIMIT %d
';

$query = $wpdb->prepare(
    $query,
    // Args: post type, post status, term taxonomy ID, number of posts
    'post', 'publish', 80, 3
);

$posts = $wpdb->get_results(
    $query,
    ARRAY_A
);
1
  • That is indeed what I ended up doing, reducing the calls from 260 to 49. In theory I also reduced them to only 12 queries but it's by using one big query with a WHERE ID IN(SELECT) which I preferred to avoid. I asked about this approach some three weeks ago and I received some very logical answers why to avoid it but for this particular case I had no alternative: wordpress.stackexchange.com/questions/151837/….
    – WPRookie82
    Jul 23, 2014 at 7:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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