2013-03-20 58 views
0

查詢1個MySQL的聯合優化

(
SELECT 
    a.image_name, a.member_id, b.username, c.image_alt , c.img_id, 
a.total_views, c.island_id, c.personal, c.date_upload, COUNT(d.img_id) AS numComm 
FROM 
    members_stats_images a, members b, members_images c, members_images_comments d 
WHERE 
    c.island_id='$island_id' AND 
    c.personal='N' AND 
    c.approved='Y' AND 
    c.is_other<>'Y' AND 
    c.member_id=b.member_id AND 
    a.member_id=b.member_id AND 
    a.image_name=c.image_name AND 
    d.img_id=c.img_id 
GROUP BY 
    d.img_id 
) 
UNION 
(
SELECT 
    a.image_name, a.member_id, b.username, c.image_alt , c.img_id, 
a.total_views, c.island_id, c.personal, c.date_upload, 0 AS numComm 
FROM 
    members_stats_images a, members b, members_images c 
WHERE 
    c.island_id='$island_id' AND 
    c.personal='N' AND 
    c.approved='Y' AND 
    c.is_other<>'Y' AND 
    c.member_id=b.member_id AND 
    a.member_id=b.member_id AND 
    a.image_name=c.image_name AND 
    c.img_id NOT IN (SELECT img_id FROM members_images_comments GROUP BY img_id) 
)   

ORDER BY 
    numComm DESC, date_upload DESC 
LIMIT 
    $set_limit, $li 

QUERY 2

(
SELECT 
    a.image_name, a.member_id, b.username, c.image_alt , c.img_id, 
a.total_views, c.island_id, c.personal, c.date_upload, COUNT(e.img_id) AS numComm 
FROM 
    members_stats_images a, members b, members_images c, members_photo_see_do d, 
members_images_comments e 
WHERE 
    c.island_id='$island_id' AND 
    c.personal='N' AND 
    c.approved='Y' AND 
    c.is_other<>'Y' AND 
    c.member_id=b.member_id AND 
    a.member_id=b.member_id AND 
    a.image_name=c.image_name AND 
    c.img_id=d.img_id AND 
    d.village_id='$village_id' AND 
    e.img_id=c.img_id 
GROUP BY 
    e.img_id 
) 
UNION 
(
SELECT 
    a.image_name, a.member_id, b.username, c.image_alt , c.img_id, 
a.total_views, c.island_id, c.personal, c.date_upload, 0 AS numComm 
FROM 
    members_stats_images a, members b, members_images c, members_photo_see_do d 
WHERE 
    c.island_id='$island_id' AND 
    c.personal='N' AND 
    c.approved='Y' AND 
    c.is_other<>'Y' AND 
    c.member_id=b.member_id AND 
    a.member_id=b.member_id AND 
    a.image_name=c.image_name AND 
    c.img_id=d.img_id AND 
    d.village_id='$village_id' AND 
    c.img_id NOT IN (SELECT img_id FROM members_images_comments GROUP BY img_id) 
)   

ORDER BY 
    numComm DESC, date_upload DESC 
LIMIT 
    $set_limit, $limit 

正如你可以看到,這兩個查詢是非常相似的。

第二個查詢在幾秒鐘內執行,而第一個查詢在超過2分鐘內執行。

任何人可以建議任何事情來改善第一個查詢嗎?

注意:涉及的所有表在所有id字段中都有索引。

編輯 在從@ G-掘金的意見,我寫上面的查詢連接,是這樣的:

SELECT 
     c.img_id, c.image_name, c.member_id, c.image_alt, c.island_id, c.personal, c.date_upload, b.username, c.island_id, c.personal, c.date_upload, 
     a.total_views, 
     COUNT(e.img_id) AS numComm 
    FROM members_images AS c 
    LEFT JOIN members_stats_images AS a ON c.image_name=a.image_name AND c.member_id=a.member_id 
    LEFT JOIN members AS b ON c.member_id=b.member_id 
    LEFT JOIN members_photo_see_do AS d ON c.img_id=d.img_id 
    LEFT JOIN members_images_comments AS e ON c.img_id=e.img_id 
    WHERE 
    c.island_id='$island_id' AND 
    c.personal='N' AND 
    c.approved='Y' AND 
    c.is_other<>'Y' AND 
    d.see_id='$see_id' 
    GROUP BY c.img_id 

它現在完全執行無延遲。

+0

你如何發佈這兩個語句和他們的索引的'EXPLAIN'? – Kermit 2013-03-20 14:06:11

回答

3

由於這兩個查詢之間的唯一區別是增加了members_photo_see_do表,因此顯然缺少一個索引來支持從它到members_images的連接。

如果沒有關於查詢和表定義的更多信息,就不可能多說。

此外,您會發現,通過使用現代JOIN語法,讀取和思考查詢都得到了相當程度的緩解。如果您採用它,您還會發現這裏的會員更願意幫助您。請在回電時使用它來編寫您的查詢。

+0

@G_Nugget是的,JOIN完成了這項工作。它現在工作完美。謝謝。 – andrew 2013-03-21 07:00:52