2012-06-04 32 views
4

我有这样的查询:为什么使用子查询的这个SQL查询非常慢?

select * 
from transaction_batch 
where id IN 
(
    select MAX(id) as id 
    from transaction_batch 
    where status_id IN (1,2) 
    group by status_id 
); 

内部查询运行速度非常快(小于0.1秒),以得到两个ID的,一个用于状态1,一个用于状态2,则它选择基于主密钥,因此它被索引。解释查询说,它使用的只是在哪里搜索135k行,而我不能为我的生活找出为什么这么慢。

+0

MySQL对于优化子查询非常愚蠢,这就是为什么它很慢。改进它的唯一方法是将它重写为JOIN(如RedFilter所示) –

回答

6
select b.* 
from transaction_batch b 
inner join (
    select max(id) as id 
    from transaction_batch 
    where status_id in (1, 2) 
    group by status_id 
) bm on b.id = bm.id 
+2

虽然我同意op应该尝试这个查询,但它根本不回答op的问题 – Lamak

+0

谢谢,这实际上很有意义(虽然它不直接回答问题,但我得到它为什么更好地工作)。 –

+0

@Lamak对于没有解释原因,我表示歉意。我不明白MySQL内部。我所能做的就是证明我发现的方式更快实证。一如既往,EXPLAIN是你的朋友。 – RedFilter

7

对于表中的每一行,内部查询都会一遍又一遍地运行。

由于在内部查询中没有对外部查询的引用,所以我建议您拆分这两个查询,并在WHERE子句中插入内部查询的结果。

+0

这实际上回答了这个问题,即使该查询在OP指出时需要.1s,您将乘以返回的每一行。如果您返回100,000行,您只需在您的手中获得10,000(167m)个查询。 –

+0

使用子查询为什么'更好'的答案很慢。 – Dom