我有这样的疑问:
SELECT va.value, vc.value
FROM votingapi_cache va
LEFT JOIN votingapi_cache vc ON vc.content_id = va.content_id
WHERE va.content_type = 'node' AND va.value_type = 'percent' AND va.tag = 'vote' AND va.function = 'average' AND vc.content_type = 'node' AND vc.tag = 'vote' AND vc.function = 'count'
ORDER BY va.value DESC, vc.value DESC LIMIT 0, 10
EXPLAIN告诉我这个查询使用临时和filesort。它在桌面上运行近10秒,行数为500k。如何优化?
架构:
索引:
根据Joachim Isaksson提供的建议,没有性能改进,EXPLAIN:
答案 0 :(得分:2)
我的建议是将联接分成两个查询......
首先,在列function, value
上构建索引,
您的第一个查询应该是获得最佳平均值,
因为这是第一个排序值,
如:
SELECT average.value, average.content_id
FROM votingapi_cache average
WHERE average.function = 'average' /* plus other filter *
ORDER BY average.value DESC LIMIT 0, 30;
然后,循环到30行以获取content_id,
并且您的第二个第二个查询是获取每个content_id的30行计数,
这意味着:
select count.value, count.content_id
FROM votingapi_cache `count`
WHERE `count`.function = 'count'
and content_id in(...30 content_id);
循环通过第二个结果并与第一个结果结合以获得最佳10个平均值+计数desc
这可以避免大规模加入
答案 1 :(得分:0)
基于@ ajreal的答案,你可以像 -
那样做SELECT averages.value, counts.value
FROM (
SELECT *
FROM votingapi_cache
WHERE function = 'average'
AND content_type = 'node'
AND tag = 'vote'
AND value_type = 'percent'
ORDER BY value DESC
LIMIT 0, 30
) AS averages
LEFT JOIN votingapi_cache counts
ON averages.content_id = counts.content_id
AND averages.content_type = counts.content_type
AND averages.value_type = counts.value_type
AND averages.tag = counts.tag
WHERE counts.function = 'count'
ORDER BY averages.value DESC, counts.value DESC
LIMIT 0, 10;