2014-09-04 131 views
0

所以,我有以下SQL優化MySQL查詢

SELECT i.id, r.full_name, i.file_name, i.lat, i.lon, c.name as 
category_name,  
    NOW() - i.timestamp AS age,   
    (SELECT count(*) FROM votes WHERE image_id = i.id) as total_votes 
FROM images i INNER JOIN registrations r 
    ON i.user_id = r.id 
INNER JOIN categories c ON i.category_id = c.id 
WHERE i.moderated=1 
ORDER BY total_votes DESC 
LIMIT 25 

這在平均10-15秒對我的本地環境中運行。

刪除ORDER BY部分將其降爲0.02ish。

有什麼方法可以加快主要語句中的排序?

更新1: 解釋下面的查詢。 Explain for query

更新2: 重寫了查詢,並增加了一些指標在

查詢

SELECT votes.image_id, count(votes.id) as total_votes, 
     images.file_name, images.lat, images.lon, NOW() - images.timestamp AS age, 
     registrations.full_name, 
     categories.name 
FROM votes 
LEFT JOIN images 
    ON votes.image_id = images.id 
LEFT JOIN registrations 
    ON images.user_id= registrations.id 
LEFT JOIN categories 
    ON images.category_id = categories.id 
GROUP BY votes.image_id 
ORDER BY total_votes DESC 
LIMIT 25 

當前解釋查詢:

enter image description here

+2

首先發布EXPLAIN的輸出以供查詢 – Prix 2014-09-04 08:42:04

+0

您是否對所有加入的列都有索引? – DanFromGermany 2014-09-04 08:42:05

+0

@Prix - 更新與解釋 – 2014-09-04 08:53:42

回答

1

你的子查詢是次優的: )

SELECT i.id, r.full_name, i.file_name, i.lat, i.lon, c.name as 
category_name,  
    NOW() - i.timestamp AS age,   
    COUNT(*) as total_votes 
FROM images i INNER JOIN registrations r 
    ON i.user_id = r.id 
LEFT JOIN votes ON i.id = votes.image_id 

INNER JOIN categories c ON i.category_id = c.id 
WHERE i.moderated=1 
GROUP BY i.id 
ORDER BY total_votes DESC 
LIMIT 25 

如果這不起作用,您將不得不提供查詢的表格結構和explain計劃。

+0

解釋添加到帖子...這是在13秒。 – 2014-09-04 08:52:03

+1

解釋計劃的列類型中的「ALL」表示完成全表掃描。你必須避免使用適當的索引。首先在您加入的列上添加索引。你應該堅持我的查詢,你的(你可以在列select_type中看到)有一個從屬子查詢,這意味着子查詢是爲結果集的每一行執行的......非常慢。 – fancyPants 2014-09-04 09:06:16

2

在表images中創建一列「votes」。如果有投票的圖像增量,如果有投票下降 - 減少。您可以並行查看錶votes並檢查是否有成功惰性然後增量。

有了這個,你將刪除你的子選擇。

之後,在images創建索引ORDER BY votes DESC和'moderated = 1`。

順便說一句,你確定你的索引是okey嗎? 還可以考慮INNER JOIN與類別。

+0

新增'votes'列可以通過'votes'表上的兩個觸發器來維護:'.. AFTER INSERT ON votes ..'(增值)和'.. AFTER DELETE ON votes ..'(遞減值) – Rimas 2014-09-04 09:17:40

0

使用TEMP TABLES進行投票和註冊表將幫助您加快查詢速度。