【问题标题】:MySQL Join Examining Every RowMySQL Join 检查每一行
【发布时间】:2011-12-13 07:59:08
【问题描述】:

我网站上的这个查询需要很长时间才能执行。我在我的网站上有一个博客和一个论坛,我已经松散地集成了,所以每个论坛帐户在博客上都有一个帐户,反之亦然。但是每个表中的 user_id 不相关,所以我一直通过用户名加入它们。

SELECT *
FROM comments AS c
INNER JOIN articles AS a ON c.article_id = a.article_id
INNER JOIN user_profiles AS p ON c.user_id = p.user_id
INNER JOIN blog_users AS b ON c.user_id = b.user_id
INNER JOIN forum_users AS f ON b.username = f.username
WHERE a.article_id =  :article_id
ORDER BY c.comment_id DESC 
LIMIT 0 , 30

当我对查询使用 explain 时,我看到最后一个连接是检查 forum_users 表中的每一行以得出超过 1,000,000 行的结果。两个表的用户名列都被索引,所有表都是 InnoDB。作为一种解决方法,我将每个用户的论坛 user_id 存储在 blog_users 表中,反之亦然,这样我就可以直接加入 user_id,这样查询运行得更快,但我想尽可能避免这样做。有没有办法我可以重新处理查询,以便用户名加入更有效?

【问题讨论】:

  • 您可以在该查询上运行EXPLAIN EXTENDED 并发布输出吗?

标签: mysql join


【解决方案1】:

表和列字符集是否相同?例如,utf8 中的 blog_users 和 latin1 中的 forum_users?如果它们不相同,mysql 将不会使用索引。您可以更改字符集,例如:

ALTER TABLE blog_users CONVERT TO CHARACTER SET utf8

如果这是问题所在,请在执行此操作之前仔细阅读文档。它可以更改列的内容。 http://dev.mysql.com/doc/refman/5.1/en/alter-table.html

【讨论】:

  • 你完全正确。 MySQL 在每个查询的 5,000,000 行表上运行 CONVERT() ,这使得查询需要永远。将两者更改为相同的字符集可以解决问题。
【解决方案2】:

两件事...您的 Comments 表是否在文章 ID 上有索引...如果没有,请获取一个...其次,您的 where 子句是指查询的 JOINED 表,而不是中的主表您的 SELECT FROM... 因为它们都有文章 ID 列,所以我会将您的 where 子句更改为

WHERE c.Article_ID = :article_ID

另外,确保索引打开

User_ID 上的 user_profiles 索引

User_ID 上的 blog_users 索引

用户名上的论坛用户索引

【讨论】:

    猜你喜欢
    • 2017-03-25
    • 1970-01-01
    • 2021-02-05
    • 2012-02-20
    • 2014-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多