2010-04-22 39 views
0

此语句效率不高,因为只有10个记录中的一个被选中,并且只有100个条目中的1个包含注释。具有嵌套SELECT的mysql语句 - 如何提高性能

我该怎么做才能改善它?

$query = "SELECT 
A,B,C, 
(SELECT COUNT(*) 
    FROM comments 
    WHERE comments.nid = header_file.nid) 
    as my_comment_count 
FROM header_file 
Where A = 'admin' " 

编辑:即使没有发现评论我想要标题记录。

回答

0

你可以尝试使用Left Join,这可能允许更好的优化:

Select a, b, c, Count(*) As my_comment_count 
From header_file h 
Left Outer Join comments c On (c.nid = h.nid) 
Group By a, b, c 
Where A = 'admin' 
+0

看起来更干净但不确定是否有任何性能提升。我也想包括记录,即使评论计数为零。如果我在where子句中找到匹配项,我宁愿挖掘注释文件。 – ernie 2010-04-22 11:02:22

+0

我使用'Left Join',所以你得到'header_file'的所有行,也是那些没有评论的。您当前的解决方案确保仅为在“Where”子句中匹配的标题读取注释。通过我的解决方案,优化器将决定哪种方式更好。 – 2010-04-22 11:32:37

1

您可以在Anid列中添加索引。

+0

gos没有说,但我检查了一倍。 – ernie 2010-04-22 11:06:34

+0

当你处理艰难的编程问题时,没有什么“不言而喻”。“ – 2010-06-04 04:01:54

1

我在这里使用的是inner join,因为它听起来像只想要包含注释的header_file记录。如果不是这种情况下,将其更改为left outer join

select h.a, h.b, h.c, c.Count 
from header_file h 
inner join (
    select nid, count(*) as Count 
    from comments 
    group by nid 
) c on c.nid = h.nid 
where h.a = 'admin' 
+0

是的,我想要标题,不管评论如何”左外连接“更合适 – ernie 2010-04-22 11:05:54

+0

我已经看过使用临时文件或”with“子句,也许在这里更合适 – ernie 2010-04-22 11:08:11

0

直接插入注释计数表中,COUNT(*)是不是很有效。

http://www.mysqlperformanceblog.com/2006/12/01/count-for-innodb-tables/

+0

@Telos:阅读该链接仔细地说,它谈到了'SELECT COUNT(*)'在没有WHERE子句的情况下选择速度很慢,这不适用于当前的情况,索引可以并将被使用 – 2010-04-22 11:35:49

+0

我刚刚在http://中找到了这个语法www.selikoff.net/2008/12/10/memo-avoid-nested-queries-in-mysql-at-all-costs/。试图使它适用于我 SET X = CallDatabase(“SELECT DISTINCT widgetId FROM widgetOrders“); CallDatabase(”SELECT id,name,price FROM widgets WHERE id IN(“+ X +”)“); – ernie 2010-04-22 11:40:25

1

从问题:

这种说法显得缺乏效率...

你怎么知道它是无效的?
你有执行计划吗?
您是否测量执行时间?
你确定它使用索引?
您评论Peter Lang的回答:... not sure if any performance gain here - 是基于什么?

你应该知道的查询执行基本的东西:

  • 大多数现代RDBMS-S具有查询优化器来分析你的SQL,并确定最优的执行计划。

你觉得某些查询是“坏”并不意味着什么。您需要检查执行计划,然后查看是否有任何可以改进性能的方法。

对于MySQL,请参阅文章:7.2.1. Optimizing Queries with EXPLAIN

你也可以从运行SQL的答案和比较的执行计划以查看是否有任何建议的解决方案的提供更好的性能。

+0

感谢您的真实性检查。 url.com/26bxbq8查询实际上比我上面的示例稍微复杂一些,现在只有有限的测试数据。我看到还有更多的索引要添加。 – ernie 2010-04-22 11:50:42