【问题标题】:Mysql join with group by query optimizationMysql join with group by 查询优化
【发布时间】:2011-10-10 21:04:44
【问题描述】:

我正在使用以下查询来获取最新文章(文章标题+作者姓名+总cmets),但是运行时间很长:

SELECT article.id, title, username, count( comment.id ) AS total_comments
FROM article
    LEFT JOIN COMMENT ON comment.article_id = article.id
    LEFT JOIN user ON article.user_id = user.id
WHERE STATUS = "open"
    AND section = "mobiles"
GROUP BY article.id
ORDER BY article.id DESC 
LIMIT 0 , 30

解释的输出是:

id  select_type     table   type    possible_keys   key     key_len     ref     rows    Extra
1   SIMPLE  article     ALL     status  NULL    NULL    NULL    77  Using where; Using temporary; Using filesort
1   SIMPLE  comment     ref     article_id  article_id  5   test.article.id     2    
1   SIMPLE  user    eq_ref  PRIMARY     PRIMARY     4   test.article.user_id    1

如何重写查询以避免创建临时表?

存储引擎是 MyISAM。这是带有索引的表的详细信息:

article 
id, title,  body,   user_id,    status,     section
primary key: id
indexes: (user_i),(status,section,id)


comment
id, article_id, user_id,    body
primary key: id
index:(article_id)


user
id, username
primary key: id

【问题讨论】:

  • 有多长?表中有多少行?
  • 400k 行大约需要 14 秒。上面的例子需要 0.5 秒。如果您从查询中删除评论连接和计数,则需要 0.025 秒。

标签: mysql query-optimization


【解决方案1】:

是否会使用子查询而不是分组连接来加快处理速度。

SELECT article.id, title, username, 
      (
       select count(*) from COMMENT 
       where comment.article_id = article.id 
       ) AS total_comments 
FROM article
    LEFT JOIN user ON article.user_id = user.id 
WHERE STATUS = "open" 
    AND section = "mobiles" 
ORDER BY article.id DESC  
LIMIT 0 , 30 

根据上一个问题How to make a nested query?

我希望这会有所帮助。

【讨论】:

    【解决方案2】:

    这个执行计划很不错。您确实无法避免创建和排序临时表:您的查询需要一个分组和排序的摘要,即,嗯,一个临时表。如果你给你的 mySQL 服务器进程更多的 RAM,你也许可以让它使用内存表而不是磁盘表。

    【讨论】:

      猜你喜欢
      • 2019-08-16
      • 2017-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-23
      • 1970-01-01
      • 2020-05-16
      相关资源
      最近更新 更多