meta_query problem

时间:2016-12-05 作者:Nelson101

我有一个meta\\u查询,它在如下情况下工作:

$args = array(
    \'number\'     => $users_per_page, 
    \'offset\'     => $offset ,
    \'orderby\'    => \'registered\', \'order\' => \'DESC\',
    \'meta_query\' => array(
        \'relation\' => \'OR\',

        array(
            \'relation\' => \'AND\',

            array(
                \'key\' => \'referrer\',
                \'value\' => $user_ID,
                \'compare\' => \'=\'

            ),

            array(
                \'key\' => \'view_type\',
                \'value\' => \'invoice\',
                \'compare\' => \'=\'
            ),
        ),

        array(
            \'relation\' => \'AND\',

            array(
                \'key\'     => \'pass_up\',
                \'value\'   => $user_ID,
                \'compare\' => \'=\'
            ),

            array(
                \'key\'     => \'view_type\',
                \'value\'   => \'invoice\',
                \'compare\' => \'=\'
            ),
        ), 
    ),
);
只要我添加一个额外的查询,查询就会超时并中断页面,而最重要的是数据库中只有5个用户。

下面的代码不起作用为什么?

$args = array(
    \'number\'     => $users_per_page, 
    \'offset\'     => $offset ,
    \'orderby\'    => \'registered\', \'order\' => \'DESC\',
    \'meta_query\' => array(
        \'relation\' => \'OR\',

        array(
            \'relation\' => \'AND\',

            array(
                \'key\'     => \'referrer\',
                \'value\'   => $user_ID,
                \'compare\' => \'=\'
            ),

            array(
                \'key\'     => \'view_type\',
                \'value\'   => \'invoice\',
                \'compare\' => \'=\'
            ),

            array(
                \'key\'     => \'pass_up\',
                \'value\'   => \'$user_ID\',
                \'compare\' => \'!=\'
            ),
        ),

        array(
            \'relation\' => \'AND\',

            array(
                \'key\' => \'pass_up\',
                \'value\' => $user_ID,
                \'compare\' => \'=\'

            ),

             array(
                \'key\' => \'view_type\',
                \'value\' => \'invoice\',
                \'compare\' => \'=\'
            ),
        ), 
    ),
);

1 个回复
最合适的回答,由SO网友:Tom J Nowell 整理而成

元查询不用于过滤返回的帖子。您可以这样使用它们,但数据库并没有为此进行优化。对于扩展和性能而言,没有什么比元查询更糟糕的了:

对其他服务器的远程请求修改和重新缩放图像,查询您不想要的内容(例如显示所有帖子but not 带有此元键的帖子)

我不能缓存这个吗

是和否。。。

缓存将改善可能的最佳结果,但您仍然必须至少运行一次查询。再加上时间问题,你的问题不会那么大,但你仍然会有问题。

如果确实缓存了结果,在一个具有较长生存期的瞬态中缓存它,并缓存了查询的Post ID,然后在新查询中使用它们,如果缓存了查询对象本身,则仍会有查询(WP\\U query会初始化内部缓存保存查询,如果缓存对象,则不会发生这种情况)

尽管所有这些都无关紧要,但如果您的查询太慢而无法完成,它将永远无法及时完成以进行缓存

我可以调整数据库吗

是和否。。

您可以向post元表添加索引,但这不是真正的修复方法,因为:

索引将只存储元值的开头,这对于简单的元值(如数字)效果很好,但对于序列化或更长的项目,它将同样缓慢,存储越多,索引的效率就越低,存储整个元值否定了索引的点,它仍然很慢,速度也不太快,你必须自己创建索引,这需要很多人不具备的技术(一些SQL foo)那么我如何过滤帖子呢Taxonomies!!

如果元查询速度很快,我们会将其用于类别和标记,但这些是作为分类法实现的。您可以添加自己的自定义分类法来实现这一点,并可以看到显著的速度提升。

幸运的是,分类查询的语法与元查询几乎相同,通过tax_query. 你还可以得到一个免费的管理UI,主题模板(taxonomy.php 等)和URL重写。您还可以获得一个免费的管理屏幕,列出您的所有术语,它们有多少篇文章,以及使用描述和术语元删除/添加/编辑它们的能力。

如果愿意,可以禁用post UI并放入自己的,以及许多其他选项。您还可以注册一个没有任何UI的分类法。我发现这些方法对于将事物相互映射很有用,例如,使用post ID作为术语的slug/name。

要注册分类,请使用register_taxonomy.

以下是一些有用的替代:

  • get_post_meta -> wp_get_post_terms
  • add_post_meta update_post_meta => wp_set_post_terms

    • get_terms
      • 奖金优化

        即使使用分类法,这也不是最好的查询。你的要求太多了!

        因此,可以添加一个钩子来进行后期保存,并在保存时进行检查。如果该职位满足任何一个条件,则设置一个附加条件,例如$user_id.\'appear-on-invoice-page\'. 现在,您的查询可以查找单个值。

        额外奖金优化我注意到view-type 对于发票,这表明一个单一的职位类型正在完成多个职位的工作。考虑使用register_post_type 创建名为invoice. 然后您可以使用\'post_type\' => \'invoice\' 在查询中,将查询的复杂性减半。这还为您提供了post archives、发票管理区域中的额外菜单选项以及许多其他好处(所有这些都可以在呼叫时打开或关闭register_post_type.

        完成所有这些操作后,您的查询可能如下所示:

        $args = array(
            \'number\'   => $users_per_page, 
            \'offset\'   => $offset ,
            \'orderby\' => \'registered\',
            \'order\' => \'DESC\',
            \'post_type\' => \'invoice\',
            \'tax_query\' => array(
                \'relation\' => \'OR\',
                array(
                    \'taxonomy\' => \'invoice_referrer\', // suggested name for your taxonomy
                    \'terms\' => $user_id
                ),
                array(
                    \'taxonomy\' => \'invoice_pass_up\',
                    \'terms\' => $user_id
                )
            )
        );
        
        关于分页的最后一点,我强烈怀疑,无论你对页面做什么,都有一个隐藏的成本,the main query. 使用分页表明您正在放弃主查询以创建第二个查询,而不是修改它。这意味着WP必须在尝试运行查询之前完成标准页面加载的所有工作,所有工作都被浪费了。

        这类似于点一份昂贵的牛排,等30分钟,然后扔掉,点一顿简单的饭。简单的饭菜会很贵,而且需要很长时间才能到达。问你想要什么不是更容易吗?

        考虑使用pre_get_posts 筛选以修改主查询,以提高速度。这甚至可以让您使用发票过帐类型存档,为您提供URL、专用模板(archive-invoice.php ), 你所需要做的就是设置tax_query 选项,以便用户只能看到与自己相关的发票。可以删除分页选项,并且您的post循环将是没有自定义的标准post循环WP_Query 对象

        我建议您在这个网站上找到许多非常好的问题/答案中的一个,这些问题/答案详细介绍了如何做到这一点

相关推荐