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 

これは .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秒実行!

idselect from purcheased... の各行に対して実行されているため、これが起こっていると思いますproducts

私はmysqlでクエリを実行しています。

id一度選択を実行しpurcheasedて、結果を再利用するように mysql に指示するにはどうすればよいですか?

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

これは、 purchase.id にインデックスがある場合にもうまく機能します。実際、これがテーブルの形式である場合、購入した (userid、reversed、id、price) のインデックスにより、これがはるかに高速になります。

于 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 に答える