2017-01-07 13 views
0

Postgresクエリが非効率的である。誰かがこのクエリを実行するのに合理的になるように正しい方向に向けることができます。私は和の行が改善/修正する方法ではなく、問題であることを知っています。 study_series_instancesとstudy_series_instance_filesに参加しながら、Postgresクエリが効率的でない

/* All Study Transfer Times */ 
WITH cte_images_duration AS 
(
    SELECT 
    ssi.study_id, 
    min(ssi.created_dt)      AS first_image_created_dt, 
    --max(ssi.created_dt)      AS last_image_created_dt, 
    max(ssi.created_dt) - min(ssi.created_dt) AS images_recieve_duration, 
    --count(ssi.study_id)      AS image_count, 
    sum( cast(btrim(ssif.file_size, 'KB') as real) ) as transferSize 
    FROM study_series_instances AS ssi, study_series_instance_files as ssif 
    where ssi.created_dt >= '2017-1-6' 
    GROUP BY ssi.study_id 
) 
SELECT 
    s.institution                   AS "Institution", 
    s.accession_no                   AS "Accession#", 
    s.modalities, 
    to_char(timezone(f.time_zone, cte1.first_image_created_dt), 'MM/DD/YYYY HH:MI:SS pm') AS "Transfer Start Date/Time", 
    --to_char(timezone(f.time_zone, cte1.last_image_created_dt), 'MM/DD/YYYY HH:MI:SS pm') AS "Transfer Stop Date/Time", 
    to_char(cte1.images_recieve_duration, 'MI:SS')           AS "Transfer Time", 
    --cte1.image_count                  AS "Image Count", 
    cte1.transferSize, 
    to_char(timezone(f.time_zone, s.study_unread_dt), 'MM/DD/YYYY HH:MI:SS pm')    AS "Unread Date/Time" 
    --to_char(timezone(f.time_zone, s.approved_dt), 'MM/DD/YYYY HH:MI:SS pm')     AS "Approved Date/Time" 
FROM 
    cte_images_duration AS cte1 
    INNER JOIN studies AS s on s.id = cte1.study_id 
    INNER JOIN facilities f ON f.id = s.facility_id 
    where s.study_unread_dt > '2017-1-6' 
ORDER BY s.accession_no 
limit 10 
+0

質問を編集し、** 'explain(analyze、verbose)' **を使用して生成された実行計画を追加してください。 [_Formatted_](http://dba.stackexchange.com/help/formatting)**テキスト**お願い、[スクリーンショットなし](http://meta.stackoverflow.com/questions/285551/why-may-i) 285557#285557) –

答えて

2

おそらくあなたは条件を見逃しています。同様に:

FROM study_series_instances AS ssi 
    JOIN study_series_instance_files as ssif ON ssif.some_field = ssi.some_field 
+3

where句の暗黙的な結合を避けるべき理由のもう1つの良い例は、次のとおりです。 –

2

別に@Dmitryと@a_horse_with_no_nameの考慮から、私はこの方法だけでなく、それを試してみた:

SELECT 
    s.institution                   AS "Institution", 
    s.accession_no                   AS "Accession#", 
    s.modalities, 
    to_char(timezone(f.time_zone, cte1.first_image_created_dt), 'MM/DD/YYYY HH:MI:SS pm') AS "Transfer Start Date/Time", 
    to_char(cte1.images_recieve_duration, 'MI:SS')           AS "Transfer Time", 
    cte1.transferSize, 
    to_char(timezone(f.time_zone, s.study_unread_dt), 'MM/DD/YYYY HH:MI:SS pm')    AS "Unread Date/Time" 
FROM 
    (SELECT 
     ssi.study_id, 
     min(ssi.created_dt)      AS first_image_created_dt, 
     max(ssi.created_dt) - min(ssi.created_dt) AS images_recieve_duration, 
     sum(cast(btrim(ssif.file_size, 'KB') as real)) AS transferSize 
    FROM 
      study_series_instances AS ssi, 
      /* Some JOIN condition is expected here */ 
      study_series_instance_files AS ssif 
    WHERE ssi.created_dt >= '2017-1-6' 
    GROUP BY ssi.study_id 
) AS cte1 
    INNER JOIN studies AS s on s.id = cte1.study_id 
    INNER JOIN facilities f ON f.id = s.facility_id 
WHERE s.study_unread_dt > '2017-1-6' 
ORDER BY s.accession_no 
LIMIT 10 

CTE式をPostgreSQLでははoptimization fencesあり、時にはそれはあなたが望むものではありません。