2009-05-21 54 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);