如何使用内部查询优化mysql查询

时间:2012-09-24 16:08:15

标签: mysql sql

我总是在以下查询上超时:

select * FROM `products` 
where 
    `active`=1 
and `group`=6 
and `id` not in (select `id` from `purcheased` where `userId`=14 and `price`>100 
and `reversed`=0)  
order by `price` asc limit 0,500

执行需要0.01秒,在这种特殊情况下返回0结果:

select `id` from `purcheased` where `userId`=14 and `price`>100 and `reversed`=0 

这在.02s中执行:

select * FROM `products` 
where 
    `active`=1 
and `group`= 6 
order by `price` asc limit 0,500 

完整查询

select * FROM `products` 
where 
    `active` = 1 
and `group` = 6 
and `id` not in (
                select `id` from `purcheased` 
                where 
                    `userId`=14 
                and `price` > 100 
                and `reversed`=0
                )
order by `price` asc limit 0,500

执行60秒!

我认为这种情况正在发生,因为正在为id的每一行执行purcheased ...中的选择products

我在mysql中运行查询。

如何告诉mysql从id执行选择purcheased一次而不是重复使用结果?

2 个答案:

答案 0 :(得分:2)

MySQL使用子查询错误优化IN和NOT IN。您可以将查询重写为相关子查询:

select *
FROM `products`
where `active`=1 and `group`=6 and 
      not exists (select `id`
                  from `purchased`
                  where `userId`=14 and `price`>100 and `reversed`=0 and
                         purchased.id = products.id
                 )  
 order by `price` asc
 limit 0,500

如果您在purchase.id上有索引,这也会更好。实际上,如果这是你的表的形式,那么购买的索引(userid,reverse,id,price)应该会更快。

答案 1 :(得分:0)

LEFT OUTER JOIN可能是你最好的选择:

select p.*
from `products` p
left outer join (
    select `id`
    from `purcheased`
    where `userId` = 14 
        and `price` > 100 
        and `reversed` = 0
) pu on p.id = pu.id
where p.`active` = 1 
    and p.`group` = 6 
    and pu.id is null
order by p.`price` 
limit 0, 500