0

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

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 

这在 0.02 秒内执行:

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 秒!

我认为这是因为 select idfrom purcheased... 正在为products.

我正在mysql中运行查询。

如何告诉 mysqlidpurcheased一次执行选择而不是重新使用结果?

4

2 回答 2

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

如果您在购买的.id 上有一个索引,这也会更好。实际上,如果这是您的表格的形式,那么购买的索引(用户 ID、反向、ID、价格)应该会更快。

于 2012-09-24T16:12:08.013 回答
0

ALEFT 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
于 2012-09-24T16:10:50.150 回答