2011-07-08 20 views
0

実行Postres 7.4(うんのアップグレード)複雑なクエリの最適化

これは、ビューのクエリであり、それは多くを使用していますが、より長い私が希望よりも時間がかかります。すべての最適化の提案?名前にIDを持つ任意のフィールドが

SELECT 
db_tbl_1.field_id, s."Field ID" AS foreign_field_id, 
s."Field Name" AS field_name, 
CASE  
    WHEN SUBSTRING(s."Field ID" FROM 0 FOR 3) = '01' THEN 'Field Label 1' 
    WHEN SUBSTRING(s."Field ID" FROM 0 FOR 4) = '321' THEN 'Field Label 1' 
    WHEN SUBSTRING(s."Field ID" FROM 0 FOR 5) = '1234' THEN 'Field Label 1' 
    WHEN SUBSTRING(s."Field ID" FROM 0 FOR 6) = '55555' THEN 'Field Label 1'  
    WHEN SUBSTRING(s."Field ID" FROM 0 FOR 3) = '76' THEN 'Field Label 2' 
END AS new_field, s.field_1, 
db_tbl_2.field_2, db_tbl_1.field_2_a, 
db_tbl_1.field_3, db_tbl_1.field_4, 
db_tbl_1.field_5, db_tbl_1.field_6, db_tbl_1.field_date_1, 
db_tbl_1.field_7, db_tbl_2.field_8 AS new_field_name, 
s."Field Date" AS field_date, db_tbl_1.created_date, 
CASE 
    WHEN (((DATE_TRUNC('month', "Field Date") + INTERVAL '2 MONTH') - "Field Date" > 60) AND 
     ((DATE_TRUNC('month', "Field Date") + INTERVAL '2 MONTH') - "Field Date" <= 92)) 
    THEN (DATE_TRUNC('month', "Field Date") + INTERVAL '2 MONTH') 
    -- the most days in a three month span can be 92 
    ELSE (DATE_TRUNC('month', "Field Date") + INTERVAL '3 MONTH') 
END AS next_date 
FROM db_schema_1.db_tbl_1, db_schema_1.db_tbl_2, "Table S" AS s 
WHERE db_tbl_1.program_level_id = db_tbl_2.id 
AND db_tbl_1.field_id = s."Another ID" 
AND (CASE 
    WHEN SUBSTRING(s."Field ID" FROM 0 FOR 3) = '01' THEN 1 
    WHEN SUBSTRING(s."Field ID" FROM 0 FOR 4) = '321' THEN 1 
    WHEN SUBSTRING(s."Field ID" FROM 0 FOR 5) = '1234' THEN 1 
    WHEN SUBSTRING(s."Field ID" FROM 0 FOR 6) = '55555' THEN 1 
    WHEN SUBSTRING(s."Field ID" FROM 0 FOR 3) = '76' THEN 1 
    ELSE 0 
END) = 1 
+0

は答えとして投稿していません'はしません。その 'SUBSTRING'を得るためには、すべての行を評価し、テーブルスキャンを行うだけです。 – JNK

+0

ちょっと、LEFT()のPostgres 7.4やPostgres版のドキュメントが見つかりません。あなたは参照を提供できますか? –

+0

それは明らかにそこにはない!私はPostgresを知らなかったと言った:) – JNK

答えて

2

をインデックス化されたクエリは、それらのすべてを評価しますので、あなたがcase文を使用している最後の文を変更してください。それが1に等しいかどうかをチェックしてください。正しい場合は他の選択肢を評価しないので、 "OR"文を試してみてください。それは少しあなたを助ける必要があります。このようなもの。 `LEFT`は、インデックスと` SUBSTRINGを使用するために、私はPostgresのを知らないが、SQL Serverで、私は `SUBSTRING`を避け、代わりにこのようなシナリオで` LEFT`を使用するので

AND (SUBSTRING(s."Field ID" FROM 0 FOR 3) = '01' OR 
    SUBSTRING(s."Field ID" FROM 0 FOR 4) = '321' OR 
    SUBSTRING(s."Field ID" FROM 0 FOR 5) = '1234' OR 
    SUBSTRING(s."Field ID" FROM 0 FOR 6) = '55555' OR 
    SUBSTRING(s."Field ID" FROM 0 FOR 3) = '76' 
) 
+0

ありがとうございました+1 –

+1

はpostgres sqlが分かりませんが、IN文があればそれを変更することができますSUBSTRING( "フィールドID" FROM 0 FOR 3)IN( '01'、 '76' )、もう少し助けてください –

+0

よくINは2桁で動作しますが、最適化やOR条件がない場合は –