这是我的查询:
SELECT qa.id,
qa.subject,
qa.category cat,
qa.keywords tags,
qa.body_html,
qa.amount,
qa.visibility,
qa.date_time,
COALESCE(u.reputation, 'N') reputation,
COALESCE(CONCAT(u.user_fname, ' ', u.user_lname), 'unknown') name,
COALESCE(u.avatar, 'anonymous.png') avatar,
(SELECT COALESCE(sum(vv.value),0)
FROM votes vv
WHERE qa.id = vv.post_id
AND 15 = vv.table_code) AS total_votes,
(SELECT COALESCE(sum(vt.total_viewed),0)
FROM viewed_total vt
WHERE qa.id = vt.post_id
AND 15 = vt.table_code
LIMIT 1) AS total_viewed
FROM qanda qa
LEFT JOIN users u ON qa.author_id = u.id
AND qa.visibility = 1
WHERE qa.type = 0
ORDER BY qa.date_time DESC
LIMIT 0,
11;
这是EXPLAIN
的结果:
看到了吗?最后一行 (vv
) 对任何索引都没有好处。这里还有 votes
表的当前索引:
无论如何,你有什么建议?我需要什么指标才能让性能更好?
最佳答案
我认为您需要将 qa.visibility = 1
从 LEFT JOIN..ON
移动到 WHERE
。完成此操作后,请获得以下索引:
qanda: INDEX(visibility, type, date_time) -- date_time must be last
这将完全处理 WHERE
、ORDER BY
和 LIMIT
——这可能是性能的最大提升。
vv and vt: INDEX(post_id, table_code) -- in either order
您似乎有(post_id, table_code, user_id)
。如果它是唯一的,则将其提升为PRIMARY KEY
并删除id
;这会带来额外的一点插入。
我假设用户
有PRIMARY KEY(id)
?
您不需要在 vt
子查询上使用 LIMIT 1
。
如果您需要进一步讨论此问题,请为每个表提供SHOW CREATE TABLE
。
关于mysql - 投票表的最佳索引是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44382393/