我在这里有一个优化问题。
我在用户表中有12000个用户,每个用户都有记录。每个用户可以是零个或多个组。我有一个包含45个组的组表和一个包含75000个记录的groups_link表(以促进多对多的关系)。
我正在创建一个查询屏幕,允许用户从用户列表中过滤用户。
具体来说,我需要帮助:选择一个组中但不在另一个组中的所有用户。
我当前的查询运行得太慢了......
SELECT U.user_id,U.user_email
FROM (sc_module_users AS U)
JOIN sc_module_users_groups_links AS group_join ON group_join.user_id = U.user_id
LEFT JOIN sc_module_users_groups_links AS excluded_group_join ON group_join.user_id = U.user_id
WHERE group_join.group_id IN (27) AND excluded_group_join.group_id NOT IN (19) OR excluded_group_join.group_id IS NULL AND U.user_subscribed=1 AND U.user_active=1
GROUP BY U.user_id,U.user_id
此查询需要9分钟才能完成,它会返回11,000条记录(12,000条记录)。
解释
以下是该查询的解释: Click here for a closer look
任何人都可以帮助我将其优化到1分钟以下......
经过3次修改后,我将其更改为
SELECT U.user_id,U.user_email FROM (sc_module_users AS U) WHERE ( user_country LIKE '%australia%' ) AND
EXISTS (SELECT group_id FROM sc_module_users_groups_links l WHERE group_id in (31) AND l.user_id=U.user_id) AND
NOT EXISTS (SELECT group_id FROM sc_module_users_groups_links l WHERE group_id in (27) AND l.user_id=U.user_id)
AND U.user_subscribed=1 AND U.user_active=1 GROUP BY U.user_id
” mucccch更快
答案 0 :(得分:1)
编辑:删除了我的查询建议,但索引内容仍应适用:
sc_module_users_groups_links
上的索引可以通过在user_id
和group_id
上创建综合索引来改进。索引中列的顺序可能会产生影响 - 我认为user_id
首先应该会有更好的效果。
您还可以尝试删除link_id
并仅使用复合主键,因为link_id
似乎没有任何其他用途。
答案 1 :(得分:0)
我认为您需要做的第一件事就是放置括号:
// should be
.. AND ( excluded_group_join.group_id NOT IN (19)
OR excluded_group_join.group_id IS NULL) AND ....