[英]Serious MySQL Performance Issue (Joins, Temporary Table, Filesort…)
我有一个用户表和一个投票表。 投票表存储对其他用户的投票。 无论好坏,投票表中的一行存储两个用户之间双向的投票。
现在,问题是当我想列出某人投票过的所有人时。
我不是 MySQL 专家,但据我所知,由于 join 语句中的 OR 条件,它需要查看整个用户表(当前 +44,000 行),它会创建一个临时表来做所以。
目前,波纹管查询大约需要两分钟,是的,两分钟才能完成。 如果我删除 OR 条件,以及 join 语句中它之后的所有内容,它会在不到半秒的时间内运行,因为它只需要查看 44,000 个用户行中的大约 17 个(解释一下)。
下面的示例,用户 ID 是9834 ,我正在尝试获取他/她自己的无票,并将被投票的用户的信息加入到结果中。
有没有更好、更快的方法来做这个查询? 或者我应该重组表格吗? 我非常希望可以通过修改查询来修复它,因为表中已经有很多用户(+44,000)和投票(+130,000),我必须迁移它们。
谢谢:)
SELECT *, votes.id as vote_id
FROM `votes`
LEFT JOIN users ON (
(
votes.user_id_1 = 9834
AND
users.uid = votes.user_id_2
)
OR
(
votes.user_id_2 = 9834
AND
users.uid = votes.user_id_1
)
)
WHERE (
(
votes.user_id_1 = 9834
AND
votes.vote_1 = 0
)
OR
(
votes.user_id_2 = 9834
AND
votes.vote_2 = 0
)
)
ORDER BY votes.updated_at DESC
LIMIT 0, 10
代替 OR,您可以执行 2 个查询的 UNION。 我知道在至少一个其他 DBMS 中这要快一个数量级的实例,我猜 MySQL 的查询优化器可能共享相同的“功能”。
SELECT whatever
FROM votes v
INNER JOIN
users u
ON v.user_id_1 = u.uid
WHERE v.user_id_2 = 9834
AND v.votes_2 = 0
UNION
SELECT whatever
FROM votes v
INNER JOIN
users u
ON v.user_id_2 = u.uid
WHERE v.user_id_1 = 9834
AND v.votes_1 = 0
ORDER BY updated_at DESC
您已经回答了自己的问题:是的,您应该重新设计表格,因为它不适合您。 它太慢了,并且需要过于复杂的查询。 幸运的是,迁移数据本质上只是执行您在此处询问的查询,但对于所有用户而不仅仅是一个用户。 (也就是说,对第一个答案建议的工会进行总和或计数。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.