如何优化mySQL以使用JOIN而不是嵌套的IN查询?

时间:2017-02-28 19:48:44

标签: mysql optimization

我有一个查询,它在多个位置组合了用户的余额,并使用嵌套子查询来组合来自customer_balance表和merchant_groups表的数据。 customer_balance表中需要第二条数据,对每个商家来说都是唯一的。

我想优化我的查询以返回总和和唯一值,即结果的顺序很重要。

例如,merchant_group中可能有三个商家:

id           |       group_id          |        group_member_id
1                       12                           36
2                       12                           70
3                       12                           106

用户可能在2个位置有余额,但在customer_balance表中不是全部:

id           |   group_member_id  |   user_id   | balance     |   personal_note     
1                      36               420         1.00         "Likes chocolate"
2                      70               420        20.00          null

请注意,余额表中没有第3行。

我最终想要的是能够提取余额的总和以及最合适的personal_note。

到目前为止,我在所有情况下都使用以下查询:

SELECT sum(c.cash_balance) as cash_balance,n.customer_note FROM customer_balance AS c
    LEFT JOIN (SELECT customer_note, user_id FROM customer_balance 
            WHERE user_id = 420 AND group_member_id = 36) AS n on c.user_id = n.user_id
    WHERE c.user_id = 420 AND c.group_id IN (SELECT group_member_id FROM merchant_group WHERE group_id = 12)

我可以适当地更改group_member_id,我将始终按照预期和相应的注释获得合并余额。即我正在寻找的是: 余额:21.00 customer_note:"喜欢巧克力" OR null(取决于group_member_id)

是否可以在不使用资源繁重的嵌套查询的情况下优化此查询,例如使用JOIN? (或其他一些方法)。

我尝试了很多选项,但无法在所有情况下都能使用它。以下是我得到的最接近的,但这并没有返回正确的注释:

SELECT sum(cb.balance), cb.personal_note FROM customer_balance AS cb
LEFT JOIN merchant_group AS mg on mg.group_member_id = cb.group_member_id 
WHERE cb.user_id = 420 && mg.group_id = 12 
ORDER BY (mg.group_member_id = 106)

我还尝试了另一个选项(但是因为丢失了查询),但是当group_member_id = 106时却没有 - 因为一个表中没有记录(但这是一个有效的用例,我想要迎合)。

谢谢!

1 个答案:

答案 0 :(得分:1)

这应该是等效的,但没有子选择

SELECT 
      sum(c.cash_balance) as cash_balance
    , n.customer_note 
FROM customer_balance AS c
LEFT JOIN customer_balance as n on ( c.user_id = n.user_id AND n.group_member_id = 36  AND n.user_id = 420 )
INNER JOIN merchant_group as mg on (  c.group_id = mg.group_member_id AND mg.group_id = 12)
WHERE c.user_id = 420