2017-01-07 162 views
0

讓Postgres查詢效率太低。希望有人能指出我的正確方向,使這個查詢合理運行。我知道總和線是問題而不是如何改進/修復它。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 -not-upload-images-code-on-so-when-asking-question-285557#285557) –

回答

2

可能您在加入study_series_instances和study_series_instance_files時錯過了一個條件。像:

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

另一個很好的例子說明爲什麼應該避免where子句中的隱式連接 –

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 

在PostgreSQL的CTE表達式optimization fences,有時候這不是你想要的。