繁体   English   中英

严重的 MySQL 性能问题(联接、临时表、文件排序……)

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM