我在这里尝试基本上找到有体育用户的用户活动所针对的地区。在acces [users]表中,大约有17K用户。每个人都可以拥有一定数量的体育兴趣和一个地区。
这里有查询查找每个拥有一项运动&至少通过活动定位的一个区域。当我们选择每个em时,体育可以达到75 [在IN查询中不太好。]
SELECT a.user, pp.courriel
FROM acces a
LEFT JOIN acces_profil_sport ap ON ap.id = a.id
LEFT JOIN profil_perso pp ON pp.id = a.id
WHERE ap.sport_id IN
(
SELECT ac.sport_id
FROM activite_sport ac
RIGHT JOIN activite a ON a.activite_id = ac.activite_id AND a.is_cron = 1 AND a.cron_processed = 0
)
AND pp.region_id IN
(
SELECT ar.region_id
FROM activite_region ar
RIGHT JOIN activite a ON a.activite_id = ar.activite_id AND a.is_cron = 1 AND a.cron_processed = 0
)
GROUP BY a.id
如果我删除了运动查找,则查询大约需要30秒才能运行。否则它需要非常永久,并使用mysql大约99%的proc。
有任何提示可以帮助吗?
[编辑:表格结构]
Acces:id(主键),用户,perso _
id(对于profil _
perso [perso _
id]的键/外键)[some-other-fields]
profil _
perso:perso _
id(主键)courriel,区域_
id,id(访问[id]的外键)[其他一些字段]
访问_
profil _
sport:id / sport _
id(双主键),niveau _
id(带有运动_
ID的双键)
答案 0 :(得分:4)
我怀疑你的索引是错误的。如果您打印出 explain select ... ,我可以更好地评论。此外,我很好奇你为什么要做左/右连接和子选择。
在我看来,这些都应该是正常连接,因为两个左连接只有在它们存在时才会起作用。如果它们为null,则由于所需的子选择匹配,您将不会获得一行。
对于正确的连接,你需要那里的ar位,这不是右侧的一部分。我要么删除它们,要么直接连接它们。我假设你正在检查看起来像未经处理的cron工作,你想保留它们。
SELECT a.user, pp.courriel
FROM acces
JOIN acces_profil_sport ap ON ap.id = a.id
JOIN profil_perso pp ON pp.id = a.id
JOIN activite_sport ac ON ac.sport_id = ap.sport_id
JOIN activite a1 ON a.activite_id = ac.activite_id AND a.is_cron = 1 AND a.cron_processed = 0
JOIN activite_region ar ON ar.region_id = pp.region_id
JOIN activite a2 ON a.activite_id = ar.activite_id AND a.is_cron = 1 AND a.cron_processed = 0
答案 1 :(得分:0)
您有is_cron
和cron_processed
的索引吗?它可以帮助加快速度。
答案 2 :(得分:0)
SELECT acces.user, courriel
FROM acces
JOIN profil_perso ON acces.id = profil_perso.id
WHERE EXISTS (SELECT 1 FROM acces_profil_sport JOIN activite_sport on acces_profil_sport.sport_id = activite_sport.sport_id JOIN activite ON activite.activite_id = activite_sport.activite_id WHERE is_cron = 1 AND cron_processed = 0 AND acces_profil_sport.id = profil_perso.id)
AND EXISTS (SELECT 1 FROM activite_region JOIN activite ON activite_region.activite_id = activite.activite_id WHERE is_cron = 1 AND cron_processed = 0 AND activite_region.region_id = profil_perso.region_id);