私が行う他のすべてのクエリは非常に高速ですが、mysql でサブクエリを使用するクエリが非常に遅くなり、最大で数分かかります。
サブクエリはおそらく悪い考えであることがわかったので、パフォーマンスに大きな影響を与えるサブクエリを使用する他のすべてのクエリで行ったように、このサブクエリを結合に変換したいと思いました。
私の他のクエリのほとんどは非常に単純ですが、これは私を夢中にさせます。
ここに例があります。
私はクライアントと請求書を持っています。クライアントには複数の請求書があります。紙幣には状態があります。また、請求書には「whatever」というパラメーターがあります。
「すべての請求書の状態が 1 または 2 で、請求書のパラメータが 2 でないすべてのクライアント」を更新する必要があります。
私はそれを行う方法を見つけることができなかったので、「状態1でも状態2でもない請求書を持たず、その請求書のパラメータが2ではないすべてのクライアント」である反転を使用しました
これらは、私が現在使用しているサブクエリを使用した 2 つのバリアントです。
update client cl , bill bi
set cl.parameter = "parameter1"
where cl.parameter="parameter2"
and bi.whatever != "2"
and bi.client_id = cl.id
and (select count(cl.id)
from bill bi
where bi.client_id = cl.id
and bi.state!="state0"
and bi.state != "state1"
) = 0;
mysql状態「データ送信中」で遅くなる
update client cl , bill bi
set cl.parameter = "parameter1"
where cl.parameter="parameter2"
and bi.whatever != "2"
and bi.client_id = cl.id
and cl.id not in (select distinct cl.id
from bill bi
where bi.client_id = cl.id
and ( bi.state!="state1"
and bi.state != "state2"
) ;
「一時テーブルにコピー中」の mysql 状態で遅くなる
私は何時間も試しましたが、遅いサブクエリなしではこれを有用なものに変換できませんでした。結合または今よりも高速なものを使用してこれを行う方法を誰か教えてもらえますか?
アップデート
DRapp のおかげで、これはまったく同じ結果を生成し、はるかに高速です。今までテストできたのは、クエリ時間は数秒で、数分前でした。
select
c.id,
sum( if( b.State IN ( "State1", "State2" ), 1, 0 )) as OkStatesCnt,
sum( if( b.State NOT IN ( "State1", "State2" ) or b.whatever=2, 1, 0 ) ) as AnyOtherState
from
client c
join bill b
ON c.id = b.client_id
where
c.parameter = "parameter2"
group by
c.id
having
OkStatesCnt > 0
AND AnyOtherState = 0
と
UPDATE client cl,
( full select query from above ) as PreQualified
set cl.parameter = "parameter1"
where cl.id = PreQualified.id