【问题标题】:How to avoid multiple querying inside a foreach using a single $wpdb?如何避免使用单个 $wpdb 在 foreach 中进行多次查询?
【发布时间】:2012-07-05 04:26:45
【问题描述】:

好吧,这会很大。正如你们许多人所知,鼓励不要在循环中多次查询数据库,但对于这项任务来说,不这样做是非常困难的——至少对我来说是这样。我们开始吧。

在 Wordpress 中,我有六类帖子。一个页面必须调用每个类别的最新帖子中的 3 个并按顺序显示它们(不混合)。

要完成该任务,首先我向数据库询问类别。然后,foreach 类别我运行一个查询以使用 $wp_query 对象检索该类别名称下的最后 3 个帖子 - 这会产生 6 个查询。类别可以更改,当然我不想每次更改代码时都被调用。

我尝试使用 $wpdb 使用一次性 MySQL (5.5) 查询来检索所有这些帖子and variables

SELECT
    DISTINCT $wpdb->posts.ID,
    $wpdb->posts.post_title,
    $wpdb->posts.post_excerpt,
    $wpdb->posts.comment_count,
    $wpdb->posts.guid,
    $wpdb->posts.post_status,
    $wpdb->posts.post_name,
    $wpdb->posts.post_date,
    $wpdb->posts.post_type,
    $wpdb->terms.slug
FROM (
      SELECT
        $wpdb->posts.ID,
        $wpdb->posts.post_title,
        $wpdb->posts.post_excerpt,
        $wpdb->posts.comment_count,
        $wpdb->posts.guid,
        $wpdb->posts.post_status,
        $wpdb->posts.post_name,
        $wpdb->posts.post_date,
        $wpdb->posts.post_type,
        $wpdb->terms.slug,
        @num := if(@group = $wpdb->terms.slug, @num + 1, 1) as row_number,
        @group := $wpdb->terms.slug
      FROM $wpdb->posts
      LEFT JOIN $wpdb->term_relationships
             ON($wpdb->posts.ID = $wpdb->term_relationships.object_id)
      LEFT JOIN $wpdb->term_taxonomy
             ON($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)
      LEFT JOIN $wpdb->terms
             ON($wpdb->term_taxonomy.term_id = $wpdb->terms.term_id)
      ORDER BY $wpdb->terms.slug ASC, $wpdb->posts.post_date DESC
    ) as $wpdb->posts

LEFT JOIN $wpdb->term_relationships
       ON($wpdb->posts.ID = $wpdb->term_relationships.object_id)
LEFT JOIN $wpdb->term_taxonomy
       ON($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)
LEFT JOIN $wpdb->terms
       ON($wpdb->term_taxonomy.term_id = $wpdb->terms.term_id)

WHERE $wpdb->posts.post_type = 'site_type'
  AND $wpdb->posts.post_status = 'publish'
  AND $wpdb->term_taxonomy.taxonomy = 'site_category'
  AND $wpdb->terms.slug IN ('cars', 'planes', 'motorcycles', '4x4', 'bicycles', 'jetpacks')
  AND row_number <= 5

ORDER BY $wpdb->terms.slug ASC, $wpdb->posts.post_date DESC
LIMIT $total    

然后,在那之后,我split the resulting array 依赖于slug。结果就是问题。

在 PHPMyAdmin 中,我执行了这个查询,row_number 不求和,每一行的值都是 1。这使得每个“X slug 下的帖子组”都没有限制,row_number &lt;= 5 不起作用。在自定义页面中,第一个类别(有 7 个帖子)显示超过 3 个。

【问题讨论】:

    标签: mysql wordpress loops foreach


    【解决方案1】:

    如果我理解你的问题,我会告诉你使用query_posts

    <?php 
        $categories=array('cat1', 'cat2', 'cat3', 'cat4', 'cat5', 'cat6');
        foreach($categories as $cat)
        {
            query_posts('category_name='.$cat.'&showposts=3&orderby=date&oredr=DESC');
            while (have_posts()) : the_post();
            ?>
                <li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
            <?php
            endwhile;
            wp_reset_query();
        }
    ?>
    

    只需将 $categories 数组中的 cat1cat2......cat6 替换为您的真实类别名称即可。

    此 sn-p 将显示我们之前分配的 $categories 数组中每个类别的最新 3 篇帖子(此处仅以标题为例)。

    【讨论】:

    • 你理解得很好,但是,调用 query_posts 6 次对性能来说是明智的吗?
    【解决方案2】:

    在再次尝试使用 MySQL 变量但失败后,我看到了另一种选择:使用 UNION ALL - has stated here,您 SELECT 每个组的 N 个数,然后用简单的话将它们联合起来.性能方面,至少在我的配置中,它的性能几乎与使用变量相同。

    因此,我构造了一个foreach 类别并为该组添加查询。

        $p = 1;
        $numb = count($products);
        global $wpdb;
    foreach($categories as $product) {
        $query .=  "(SELECT $wpdb->posts.ID, $wpdb->posts.post_title, $wpdb->posts.post_excerpt, $wpdb->posts.comment_count, $wpdb->posts.guid,
            $wpdb->posts.post_status,
            $wpdb->posts.post_name,
            $wpdb->posts.post_date,
            $wpdb->posts.post_type,
            $wpdb->terms.slug
        FROM $wpdb->posts
        LEFT JOIN $wpdb->term_relationships
            ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id)
        LEFT JOIN $wpdb->term_taxonomy
            ON($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)
        LEFT JOIN $wpdb->terms
            ON($wpdb->term_taxonomy.term_id = $wpdb->terms.term_id)
        WHERE $wpdb->posts.post_type = 'pb_review'
        AND $wpdb->posts.post_status = 'publish'
        AND $wpdb->term_taxonomy.taxonomy = 'product_reviews'
        AND $wpdb->terms.slug IN ('$product->slug')
        ORDER BY $wpdb->posts.post_date DESC
        LIMIT 3)" . ($p == $numb ? '' : ' UNION ALL ');
        $p++;
    }
    

    在 $query 构造完成后,我将它作为变量传递给 $wpdb 和瞧:

    $productos_query = $wpdb->get_results($query, OBJECT);
    

    为什么变量不起作用,将 +1 添加到 row_number?我的猜测是因为我使用的是LEFT JOIN,但请做我的客人。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-07-05
      • 2016-01-23
      • 1970-01-01
      • 1970-01-01
      • 2015-02-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多