2016-12-26 3 views
-1

さまざまなテーブルから条件付きデータをフェッチする既存のSQLクエリは非常に遅く、クエリを最適化する方法を理解する必要があります。sqlite_3クエリを最適化する方法は?

既存のクエリは、いくつかの条件で 'Material'テーブルからマテリアル情報を取得しようとしています。 'Config'テーブルに 'printer'がある場合、 'Config'テーブルに 'materials'の情報のみを返します。 '構成'テーブルに 'プリンタ'がない場合、 '利用可能な品目'テーブルのすべての品目の情報を返します。これは、大文字と小文字の結合を使用して処理されます。しかし、必要な表現は 'join'と 'where'節で繰り返されます。そこで、いくつかのサブクエリの「結果」を保存し、後でそれを再利用する方法が必要でした。

(SELECT EXISTS (SELECT 1 FROM available_material_printmode_config 
WHERE printer_name ='123' LIMIT 1)) 

(SELECT case when material_name is null then 0 else 1 end 
FROM available_material_printmode_config 
WHERE printer_name ='123' and printmode_name = '2' LIMIT 1) 
を:彼らが繰り返されると、下記のSQL文の結果を再利用する方法があれば知りたいと思った

select m.name from material m 

left join available_material_printmode_config ac on ac.material_name = m.name and 
(SELECT EXISTS (SELECT 1 FROM available_material_printmode_config 
WHERE printer_name ='123' LIMIT 1)) and 
(SELECT case when material_name is null then 0 else 1 end 
FROM available_material_printmode_config WHERE printer_name ='123' 
and printmode_name = '2' LIMIT 1) 

left join available_materials am1 on am1.material_name = m.name 
and ((SELECT EXISTS (SELECT 1 FROM available_material_printmode_config 
WHERE printer_name ='123' LIMIT 1)) !=1 
or ((SELECT EXISTS (SELECT 1 FROM available_material_printmode_config 
WHERE printer_name ='123' LIMIT 1)) 
and (SELECT case when material_name is null then 1 else 0 end 
FROM available_material_printmode_config WHERE printer_name ='123' 
and printmode_name = '2' LIMIT 1))) 

where 
case 
when 'true' == (select case when exists 
(select distinct 1 from available_material_printmode_config where printer_name = '123') 
THEN 'true' ELSE 'false' END) 
and (SELECT case when material_name is null then 0 else 1 end 
FROM available_material_printmode_config WHERE printer_name ='123' 
and printmode_name = '2' LIMIT 1) 
then 
ac.printer_name = '123' and ac.printmode_name = '2' 
else 
am1.printer_name = '123' 
end 

- :私はこのようになりますsqliteのクエリを持っています

これは私が今使っている最後のクエリです:

select m.name, m.color from material m inner join 
available_material_printmode_config ac on ac.material_name is not null 
and m.name=ac.material_name  
where ac.printmode_name='2' and ac.printer_name='123' 
UNION 
select m.name,m.color from material m 
inner join available_materials am on m.name=am.material_name 
where (not exists (select distinct 1 from available_material_printmode_config 
where printer_name = am.printer_name limit 1) 
or exists (select 1 from available_material_printmode_config 
where printer_name = am.printer_name and printmode_name = '2' 
and material_name is null LIMIT 1)) and am.printer_name='123'; 

受け入れ答えからインスピレーションを得た私の元のクエリはaleternative 1の20個のステップを持っていたし、最後のクエリが9つのステップがあり、28個のステップを持っていました。手順は基本的には私がクエリプラン SQLコマンドを使用して取得カウントです。

答えて

2

あなたの2つのセットのユニオンクエリを考えてみましょう。データやスキーマは掲載されていませんが、以下に調整が必要な場合があります。また、サブクエリは現在外側のクエリ行に相関している:

SELECT m.name 
FROM material m 
LEFT JOIN available_material_printmode_config ac 
    ON ac.material_name = m.name 
WHERE EXISTS 
    (SELECT 1 FROM available_material_printmode_config sub   
    WHERE ac.printer_name = sub.printer_name 
     AND ac.printmode_name = sub.print mode_name) 
AND ac.printer_name = '123' AND ac.printmode_name = '2' 

UNION 

SELECT m.name 
FROM material m 
LEFT JOIN available_materials am 
    ON am.material_name = m.name 
WHERE NOT EXISTS 
    (SELECT 1 FROM available_material_printmode_config sub 
    WHERE am.printer_name = sub.printer_name 
     AND sub.printmode_name = '2') 
AND am.printer_name = '123' 
+0

(available_material_printmode_configサブ am.printer_name = sub.printer_name から1を選択し、sub.printmode_name = '2')これが繰り返されなければなりませんか? –

+0

組合は意味をなさない。編集を確認してください。 –

+0

編集しても、EXISTSサブクエリは外部クエリと相関がないので、一度に1つの行ではなくテーブル全体をチェックします。 SQLが動作するかどうかを確認するためにデータをチェックしてください。 – Parfait

関連する問題