2012-09-24 35 views
0

我一直都想與優化的MySQL查詢超時以下查詢:如何與內部查詢

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

我認爲這是因爲選擇idpurcheased ...正在執行的products的每一行。

我在mysql中運行查詢。

我該如何告訴mysql執行從purcheased一次選擇id並重新使用結果?

+0

您的表名中的錯字:* purcheased *應該*購買* – RedFilter

回答

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 
+0

謝謝!這太棒了! –

+0

爲什麼downvote? – RedFilter

2

的MySQL misoptimizes 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 

如果您有購物目錄中的索引,這也會更好。實際上,如果這是你的表格的形式,那麼爲(userid,reversed,id,price)購買的索引應該使這個速度更快。

+0

剛剛嘗試過,執行時間沒有改變 –