我总是在以下查询上超时:
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
一次而不是重复使用结果?
答案 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