优化MySQL查询

时间:2014-09-04 08:38:43

标签: mysql sql

所以我有以下SQL

 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

3 个答案:

答案 0 :(得分:2)

在表格images中创建一列“votes”。如果已经投票支持图像 - 增量,如果已经投票减少 - 减少。你可以平行地拥有表votes并检查是否成功惰性然后增加。

使用此功能,您将删除此子选择。

images之后使用ORDER BY votes DESC和'moderated = 1`创建INDEX。

顺便说一下,你确定你的索引是好的吗? 还要考虑INNER JOIN和类别。

答案 1 :(得分: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查询计划。

答案 2 :(得分:0)

使用TEMP TABLES进行投票和注册表将帮助您加快查询速度。