2013-11-15 87 views
1

我无法弄清楚为什么在Query2中的'order by'子句导致它超过一分钟,而第一个子句立即返回结果。有没有更好的办法 '由序' 要做到这一点Mysql Order By By Group By造成查询速度很慢

快速:

select c.id, max(date(a.sent)) as sent, 
    if(c.id in (select id from bin where (num=1 or num=2)),1,0) as done 
from test c, test2 a 
where c.id=a.id 
group by c.id 
limit 1; 

select c.id, max(date(a.sent)) as sent, 
    if(c.id in (select id from bin where (num=1 or num=2)),1,0) as done 
from test c, test2 a 
where c.id=a.id 
group by c.id 
order by done, sent 
limit 1; 

回答

1

这是因为在order by子句中的 “列” 并不是真正的列,但用于在查询中其他地方进行计算的别名。因此,它们没有编入索引,服务器必须立即订购它们。使用联接来计算done,而不是子查询,可能会加速很多。

+0

对于大多数现代的RDBMS,子查询并不比联接更差。对于旧的关系型数据库来说,这只是真的,他们无法弄清楚两者是否相同。今天,有时一个子查询是一个更好的方法去...这一切都取决于。 –

0

如果您要回收所有记录,排序不应该花费太多时间,即使它们是计算/非索引字段。但是,您正在使用“限制1”。这改变了优化器的方法。

在第一种情况下,您按ID排序。既然你有“限制1”,并且ID可能有一个索引,优化器可以通过ID去ID,当它得到一个匹配WHERE子句的记录时,它可以返回。

但是,在第二个查询中,即使您只需要1条记录,优化程序也不会知道哪个是除非计算整个集合(因为您没有“限制1”),然后返回只有第一个。

取下“限制1”并比较两个查询。如果差异仍然存在,则可能是另一个问题。

很难说什么最适合您的卷。试试这个查询:

select id, max(date(sent)) as sent, 0 As done 
from test2 
where exists (select 1 from bin where bin.id=test2.id and num not in (1,2)) 
group by id 
union all 
select id, max(date(sent)) as sent, 1 As done 
from test2 
where exists (select 1 from bin where bin.id=test2.id and num in (1,2)) 
group by id 
order by done, sent 
limit 1 

SQL Fiddle is here如果你想调整它。

我遗漏了测试表,因为您没有取回除了ID之外的任何字段,而ID已经在test2上。如果你需要测试其他领域,你将不得不调整它。

+0

你是对的。我只运行了没有限制1的两个查询,而“快速”版本实际上比“快速”版本跑得慢。很明显,“限制1”正在产生影响。是的,我真的只想返回一个记录。有什么更好的方法来做到这一点? – user2029890

+0

谢谢。绝对更快,但仍然不能快速使用。我确实需要'测试'表中的数据,我只是没有在示例中包含它。一张桌子有大约30万条记录,另一张大约有200万条记录。 – user2029890

+0

好的,这三个表中每一个有多少记录:test,test2,bin? –