2009-05-21 44 views
0

我想在这里基本上找到确实有活动所针对的运动区域的用户。在acces [用户]表中,大约有17K用户。每个人都可以拥有一定数量的体育兴趣和一个地区。对查询优化的洞察力

这里的查询会查找每个有一项运动的用户&至少有一个区域是通过活动定位的。当我们选择每一个时,运动可以达到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的proc约99%。

任何提示帮助吗?

[编辑:表结构]
艾策斯:ID(主键),用户,perso _ ID(键/外键PROFIL _ perso [perso _ ID])[一些-其他字段]
PROFIL _ perso:perso _ id(主键)courriel,region _ id,id(外键访问[id])[某些其他字段]
acces _ profil _ sport:id/sport _ id(双主键), niveau _ id(双键运动_ id)

+1

你能列出你正在使用哪些表以及哪些列是什么? – 2009-05-21 17:28:05

+0

您的表格是否已正确编入索引?虽然这个查询不是很好,但它似乎不应该在您正在使用的相对较小的数据集上占用*那么长。 – 2009-05-21 17:39:55

+0

您在编辑时没有给我们2个表格。向我展示一个关于该查询的“解释”,也将为索引可能丢失的位置提供很多见解。 – 2009-05-21 18:11:41

回答

4

I怀疑你的索引是错的。如果你打印出一个解释选择...,我可以更好地评论。此外,我很好奇你为什么要做左/右连接和子选择。

在我看来,这些应该都是正常的连接,因为这两个左连接只有在存在时才有效。如果它们出现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 
0

你对is_croncron_processed指数?它可以帮助加快速度。

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);