对Wordpress / Woocommerce自定义SQL查询进行故障排除以进行报告

时间:2015-05-15 10:42:51

标签: mysql sql wordpress woocommerce query-optimization

希望这是正确的论坛,我的问题似乎与堆栈交换社区重叠,所以这似乎是最好的。

我在wordpress网站上为我的WooCommerce订单提供了一些自定义报告。我有一个本地冻结的查询,这意味着在我的本地主机中我的CPU达到100%并且它永远不会完成,我不明白为什么。这里的重点是查询:

SELECT SUM(postmeta.meta_value)
FROM pca_postmeta AS postmeta
LEFT JOIN pca_woocommerce_order_items AS orders ON orders.order_id = postmeta.post_id
WHERE postmeta.meta_key = '_order_total'
AND orders.order_item_id IN (
    SELECT item_meta.order_item_id 
    FROM pca_woocommerce_order_itemmeta AS item_meta 
    LEFT JOIN pca_woocommerce_order_items AS orders ON item_meta.order_item_id = orders.order_item_id 
    LEFT JOIN pca_posts AS posts ON posts.ID = orders.order_id 
    WHERE item_meta.meta_value = '23563' 
    AND posts.post_status IN ('wc-processing','wc-completed') 
    GROUP BY orders.order_id
)

正如您可以看到,此处的目标是获取此特定广告系列( 23563 )中所有订单的总和。嵌套查询完全按照预期工作,只返回一个ID列表,如下所示:

注意: 如果2.6289秒很长,只有总共返回65,虽然总共有148220

enter image description here

问题是此查询似乎不喜欢嵌套部分。有什么建议?完全不同的方法?

P.S。我在其他时间也使用该嵌套查询,以便在我的php报告类中按广告系列ID表示所有订单。但是对于我的问题,PHP与它无关。

  

更新/关注:

是否可以将此转换为连接,如下所述:Using a SELECT statement within a WHERE clause?我对我的SQL有点了解,所以不确定我会怎么做,但似乎很有希望

1 个答案:

答案 0 :(得分:1)

Qt::NoModifier  
Qt::ShiftModifier   
Qt::ControlModifier
Qt::AltModifier 
Qt::MetaModifier    
Qt::KeypadModifier  
Qt::GroupSwitchModifier

没有意义,因为您只选择了GROUP BY orders.order_id

order_item_id将受益于

pca_woocommerce_order_itemmeta

这个可能是一个等效的查询,但是避免使用INDEX(meta_value, order_item_id)

IN(SELECT...)

修改

我所做的一些原则。在这里,我猜测优化器将使用各种可能的查询公式。

  • 我摆脱了SELECT SUM(pm.meta_value) FROM ( SELECT im.order_item_id FROM pca_woocommerce_order_itemmeta AS im LEFT JOIN pca_woocommerce_order_items AS o ON im.order_item_id = o.order_item_id LEFT JOIN pca_posts AS posts ON posts.ID = o.order_id WHERE im.meta_value = '23563' AND posts.post_status IN ('wc-processing','wc-completed') GROUP BY o.order_id ) AS w JOIN pca_woocommerce_order_items AS o ON w.order_item_id = o.order_item_id JOIN pca_postmeta AS pm ON o.order_id = pm.post_id WHERE pm.meta_key = '_order_total' - 这个可能改变了输出。但我需要避免LEFT哪些不可优化。
  • 通过在“表”列表中加入一个子查询,优化器将(几乎可以肯定)从子查询开始,并对其他表执行“嵌套循环连接”。 NLJ是执行查询的常用方法。
  • 像这样的子选择没有索引,因此需要先按顺序排列,否则效率会非常低。
  • 如果没有子查询,优化器通常喜欢从LEFT JOIN ( SELECT ... )子句中包含哪些表开始。
  • 以子查询“表格”开头的要求比根据WHERE选择表格的要求更强。
  • 在子查询中,唯一的“=”测试(WHERE pm.meta_key = '_order_total')为该组JOIN提供了可能的起点。它不是WHERE im.meta_value = '23563的“正确”,这进一步增强了这一点。因此,我建议索引。