优化 SQL 查询

Posted

技术标签:

【中文标题】优化 SQL 查询【英文标题】:Optimize SQL-query 【发布时间】:2009-02-21 11:33:09 【问题描述】:

我有以下查询:

Select diary_id, 
   (select count(*) 
    from `comments` as c 
    where c.d_id = d.diary_id) as diary_comments 
From `diaries` as d

这需要很长时间(在我的情况下接近 0.119415)。 如何让它更快?

我只看到一种方法:对我的主查询中的每一行的评论编号进行额外查询。但这就像在循环中进行查询一样。比如:

while ($r = mysql_fetch_array($res))

   $comments = mysql_query("select count(*) from `comments` where d_id = ".$r['diary_id']);

我认为这是一个糟糕的策略。还有其他建议吗?

【问题讨论】:

【参考方案1】:
SELECT d.diary_id, count(c.d_id) as diary_comments 
FROM diaries d
LEFT OUTER JOIN comments c ON (d.diary_id = c.d_id)
GROUP BY d.diary_id

我似乎被否决了,因为您实际上可以仅从日记表中检索所需的所有数据。我假设这是一个简化的示例,实际上需要 diaries 表中的其他字段,而且此方法会返回没有 cmets 的记录。如果您不需要这两件事中的任何一个,那么我会选择另一个答案。

【讨论】:

【参考方案2】:

看起来您在 cmets 表中拥有您需要的所有数据,所以我看不出连接或子查询的原因。

SELECT d_id AS diary_id, COUNT(*) AS diary_comments
FROM `comments`
GROUP BY d_id

【讨论】:

好点。尽管他可能想要显示没有 cmets 的日记项目。【参考方案3】:

tomhaigh 的解决方案肯定加一个,在这种情况下,group by 正是这种情况。

另一个选项永远值得记住,您在这里有两个选择。首先在每次读取时计算值,其次在每次写入时计算并存储结果。在第二种情况下,您需要在日记中添加一个名为“cmets_count”的字段,这需要在插入新评论时增加。显然,这可能不如计算每次读取的计数准确,并且会减慢您的写入速度。但是,如果读取性能受到损害并且写入明显不如读取常见,那么这可能是考虑问题的一种方便方法。

【讨论】:

以上是关于优化 SQL 查询的主要内容,如果未能解决你的问题,请参考以下文章

数据库牛人是如何进行SQL优化的?

如何做SQL优化?优化SQL语句,提高SQL查询效率。Effective MySQL之SQL语句最优化

sql查询优化 索引优化

SQL优化----百万数据查询优化

优化SQL查询:如何写出高性能SQL语句

SQL数据库查询的优化