2014-12-12 6 views
0

По существу, я пытаюсь увидеть, если c_DSS_PG_Submission.PtNum находится в таблице temp ED_MLP_ATTN, и если она затем назначает 'MLP + ATTN'. Только для таблицы temp требуется около 2 минут для генерации и имеет ~ 1000 строк, таблица PG имеет около ~ 300 строк, поэтому они не являются большими таблицами. Однако следующий запрос выполняется в течение 20 + минут. Вы порекомендовали бы что-нибудь другое с запросом? Я попытался изменить существующее на IN, но с той же медленной производительностью.slow performance with exists case statement

WITH ed_mlp_attn 
      AS (SELECT smsdss.c_cfvhs_emstat_chart.visitno , 
         CAST (smsdss.c_cfvhs_emstat_chart.dschdate AS DATE) AS dschdate 
       FROM  smsdss.c_cfvhs_emstat_chart 
         INNER JOIN smsdss.c_cfvhs_emstat_oi_header ON smsdss.c_cfvhs_emstat_chart.chrtno = c_cfvhs_emstat_oi_header.chartno 
          COLLATE SQL_Latin1_General_Pref_CP1_CI_AS 
         INNER JOIN smsdss.c_cfvhs_emstat_oi_detail ON c_cfvhs_emstat_oi_header.oi_header_id = smsdss.c_cfvhs_emstat_oi_detail.oi_header_id 
         INNER JOIN smsdss.c_cfvhs_emstat_physician ON smsdss.c_cfvhs_emstat_chart.erphys = smsdss.c_cfvhs_emstat_physician.physid 
           COLLATE SQL_Latin1_General_Pref_CP1_CI_AS 
       WHERE smsdss.c_cfvhs_emstat_chart.dschdate >= DATEADD(mm, -1, 
                   GETDATE()) 
         AND smsdss.c_cfvhs_emstat_chart.dispocd <> 'DXERR' 
         AND c_cfvhs_emstat_oi_detail.VALUE IN ('21504', 
                   '21505') 
         AND smsdss.c_cfvhs_emstat_physician.code1 = 'RES' 
      ) 
    SELECT atndrname , 
      atndrno , 
      CASE WHEN EXISTS (SELECT 1 
           FROM  ed_mlp_attn 
           WHERE visitno COLLATE SQL_Latin1_General_Pref_CP1_CI_AS = smsdss.c_dss_pg_submission.ptnum) 
       THEN 'MLP+ATTN' 
       ELSE 'NO' 
      END AS ed_prov_type 
    FROM smsdss.c_dss_pg_submission 
    WHERE date_run = '2014-12-12' 
      AND surveydesignator IN ('ER0101', 'PE0101') 
    ORDER BY surveydesignator , 
      ptnum 
+0

, с какими rdbms вы имеете дело? вы проверяли индексы? любой намек на инструменты анализа ваших rdbms? – Paolo

+1

Вместо использования коррелированного подзапроса вы можете попытаться использовать внешнее соединение. Как всегда, хотя с производительностью, вам нужно будет проверить себя. Убедитесь, что у вас есть соответствующие индексы. – sgeddes

+0

MSSQl server 2008. Мой оценочный план выполнения имеет 68% стоимости для кластерного сканирования индекса OI_HEADER. Когда i SELECT name AS Stats, STATS_DATE (object_id, stats_id) AS LastStatsUpdate FROM sys.stats говорит, что таблица была обновлена ​​05.12.2014. Означает ли это, что он также был проиндексирован? или я должен переиндексировать? – user3101182

ответ

1

Во-первых, КТР не то же самое, как временную таблицу, обратите внимание на информацию в @JodyT's comment.

Запрос в CTE будет выполнен для каждой строки, возвращаемой внешним запросом.

Это значительно замедлит запрос, который я ожидаю. Я бы разбил текущий CTE на фактическую временную таблицу в качестве отправной точки для повышения производительности.

ПРИМЕЧАНИЕ: Я использовал псевдонимы для имен таблиц, чтобы уменьшить количество SQL и сделать его немного легче читать.

SELECT chart.visitno , CAST (chart.dschdate AS DATE) AS dschdate 
INTO #TEMP 
FROM c_cfvhs_emstat_chart chart 
     INNER JOIN c_cfvhs_emstat_oi_header header 
      ON chart.chrtno = header.chartno COLLATE SQL_Latin1_General_Pref_CP1_CI_AS 
     INNER JOIN c_cfvhs_emstat_oi_detail detail 
      ON header.oi_header_id = detail.oi_header_id 
     INNER JOIN c_cfvhs_emstat_physician physician 
      ON chart.erphys = physician.physid COLLATE SQL_Latin1_General_Pref_CP1_CI_AS 
WHERE chart.dschdate >= DATEADD(mm, -1, GETDATE()) 
     AND chart.dispocd <> 'DXERR' 
     AND detail.VALUE IN ('21504', '21505') 
     AND physician.code1 = 'RES' 

Тогда запрос, что:

SELECT atndrname , 
     atndrno , 
     CASE WHEN EXISTS (SELECT 1 
          FROM  #TEMP 
          WHERE visitno COLLATE SQL_Latin1_General_Pref_CP1_CI_AS = smsdss.c_dss_pg_submission.ptnum) 
      THEN 'MLP+ATTN' 
      ELSE 'NO' 
     END AS ed_prov_type 
FROM smsdss.c_dss_pg_submission 
WHERE date_run = '2014-12-12' 
     AND surveydesignator IN ('ER0101', 'PE0101') 
ORDER BY surveydesignator , ptnum 

Преодолевая его вниз, как это должно повысить производительность, в определенной степени, но без информации об индексах и план выполнения, это трудно представить дальнейшие рекомендации.