2016-06-13 1 views
0

Ниже представлен запрос на получение записей, счетчик которых (SGT_DISBURSEMENT_REQUEST) равен только одному. Он отлично работает. Но производительность была мудрой, так как у нас было 100 000 записей.Альтернативный способ существует с условием наличия

Есть ли лучший способ сделать это?

SELECT PA.PERSON_ID, 
    PA.PERSON_ACCOUNT_ID, 
    DR.DISBURSEMENT_REQUEST_ID, 
    SUM 
    ( 
     ISNULL(CD.EE_PRE_TAX_AMT,0) + 
     ISNULL(CD.EE_ADDL_PRE_TAX_AMT,0) 
    ) AS EE_PRE_TAX_CONTRIB, 
    DD.PRE_TAX_AMOUNT AS DISB_DTL_PRE_TAX_AMOUNT, 
    SUM 
    ( ISNULL(CD.EE_POST_TAX_AMT,0) + 
     ISNULL(CD.EE_ADDL_POST_TAX_AMT,0) 
    ) AS EE_POST_TAX_CONTRIB, 
    DD.POST_TAX_AMOUNT AS DISB_DTL_POST_TAX_AMOUNT 
    FROM SGT_DISBURSEMENT_REQUEST DR 
    INNER JOIN SGT_DISBURSEMENT_DETAIL DD ON DR.DISBURSEMENT_REQUEST_ID = DD.DISBURSEMENT_REQUEST_ID 
    INNER JOIN SGT_PERSON_ACCOUNT PA ON PA.PERSON_ACCOUNT_ID = DR.PERSON_ACCOUNT_ID 
    INNER JOIN SGT_CONTRIB_DTL CD ON CD.PERSON_ACCOUNT_ID = PA.PERSON_ACCOUNT_ID 
    WHERE DR.REQUEST_CATEGORY_VALUE = 'REFD' AND 
     DD.DETAIL_CATEGORY_VALUE = 'REFD' AND 
     CD.STATUS_VALUE = 'VALD' AND 
     CD.POSTED_DATE <= DR.ACCEPTED_TO_PAYROLL_DATE AND 
     DR.DISBURSEMENT_STATUS_VALUE <> 'CANL' AND 
     EXISTS 
     (
      SELECT 1 FROM SGT_DISBURSEMENT_REQUEST SDR1 
      INNER JOIN SGT_DISBURSEMENT_DETAIL SDD1 ON SDD1.DISBURSEMENT_REQUEST_ID = SDR1.DISBURSEMENT_REQUEST_ID 
      WHERE SDR1.PERSON_ACCOUNT_ID = DR.PERSON_ACCOUNT_ID and SDD1.DETAIL_CATEGORY_VALUE = DD.DETAIL_CATEGORY_VALUE 
      GROUP BY SDR1.PERSON_ACCOUNT_ID 
      HAVING COUNT(*) = 1 
     ) 
    GROUP BY 
     PA.PERSON_ID, PA.PERSON_ACCOUNT_ID, DR.DISBURSEMENT_REQUEST_ID, DD.PRE_TAX_AMOUNT, DD.POST_TAX_AMOUNT 

ответ

0

Для улучшения эффективности вы можете иметь условия фильтра в разделе «Присоединение» вместо предложения where. В этом случае каждое объединение ограничивает результаты еще меньшим количеством строк.

 SELECT PA.PERSON_ID, 
      PA.PERSON_ACCOUNT_ID, 
      DR.DISBURSEMENT_REQUEST_ID, 
      SUM 
      ( 
       ISNULL(CD.EE_PRE_TAX_AMT,0) + 
       ISNULL(CD.EE_ADDL_PRE_TAX_AMT,0) 
      ) AS EE_PRE_TAX_CONTRIB, 
      DD.PRE_TAX_AMOUNT AS DISB_DTL_PRE_TAX_AMOUNT, 
      SUM 
      ( ISNULL(CD.EE_POST_TAX_AMT,0) + 
       ISNULL(CD.EE_ADDL_POST_TAX_AMT,0) 
      ) AS EE_POST_TAX_CONTRIB, 
      DD.POST_TAX_AMOUNT AS DISB_DTL_POST_TAX_AMOUNT 
      FROM SGT_DISBURSEMENT_REQUEST DR 
      INNER JOIN SGT_DISBURSEMENT_DETAIL DD ON  DR.DISBURSEMENT_REQUEST_ID = DD.DISBURSEMENT_REQUEST_ID AND DR.REQUEST_CATEGORY_VALUE = 'REFD' AND 
       DD.DETAIL_CATEGORY_VALUE = 'REFD' AND DR.DISBURSEMENT_STATUS_VALUE <> 'CANL' 
      INNER JOIN SGT_PERSON_ACCOUNT PA ON PA.PERSON_ACCOUNT_ID = DR.PERSON_ACCOUNT_ID 
      INNER JOIN SGT_CONTRIB_DTL CD ON CD.PERSON_ACCOUNT_ID = PA.PERSON_ACCOUNT_ID AND CD.STATUS_VALUE = 'VALD' AND 
       CD.POSTED_DATE <= DR.ACCEPTED_TO_PAYROLL_DATE 
      WHERE EXISTS 
       (
        SELECT 1 FROM SGT_DISBURSEMENT_REQUEST SDR1 
        INNER JOIN SGT_DISBURSEMENT_DETAIL SDD1 ON SDD1.DISBURSEMENT_REQUEST_ID = SDR1.DISBURSEMENT_REQUEST_ID 
        WHERE SDR1.PERSON_ACCOUNT_ID = DR.PERSON_ACCOUNT_ID and SDD1.DETAIL_CATEGORY_VALUE = DD.DETAIL_CATEGORY_VALUE 
        GROUP BY SDR1.PERSON_ACCOUNT_ID 
        HAVING COUNT(*) = 1 
       ) 
      GROUP BY 
       PA.PERSON_ID, PA.PERSON_ACCOUNT_ID, DR.DISBURSEMENT_REQUEST_ID, DD.PRE_TAX_AMOUNT, DD.POST_TAX_AMOUNT 
0

если вы используете счет более это должно дать тот же результат, и лучше для производительности:

select * from (
SELECT PA.PERSON_ID, 
    PA.PERSON_ACCOUNT_ID, 
    DR.DISBURSEMENT_REQUEST_ID, 
    SUM 
    ( 
     ISNULL(CD.EE_PRE_TAX_AMT,0) + 
     ISNULL(CD.EE_ADDL_PRE_TAX_AMT,0) 
    ) AS EE_PRE_TAX_CONTRIB, 
    DD.PRE_TAX_AMOUNT AS DISB_DTL_PRE_TAX_AMOUNT, 
    SUM 
    ( ISNULL(CD.EE_POST_TAX_AMT,0) + 
     ISNULL(CD.EE_ADDL_POST_TAX_AMT,0) 
    ) AS EE_POST_TAX_CONTRIB, 
    DD.POST_TAX_AMOUNT AS DISB_DTL_POST_TAX_AMOUNT 
    ,count(*) over(partition by PA.PERSON_ACCOUNT_ID) as ct 
    FROM SGT_DISBURSEMENT_REQUEST DR 
    INNER JOIN SGT_DISBURSEMENT_DETAIL DD ON DR.DISBURSEMENT_REQUEST_ID = DD.DISBURSEMENT_REQUEST_ID 
    INNER JOIN SGT_PERSON_ACCOUNT PA ON PA.PERSON_ACCOUNT_ID = DR.PERSON_ACCOUNT_ID 
    INNER JOIN SGT_CONTRIB_DTL CD ON CD.PERSON_ACCOUNT_ID = PA.PERSON_ACCOUNT_ID 
    WHERE DR.REQUEST_CATEGORY_VALUE = 'REFD' AND 
     DD.DETAIL_CATEGORY_VALUE = 'REFD' AND 
     CD.STATUS_VALUE = 'VALD' AND 
     CD.POSTED_DATE <= DR.ACCEPTED_TO_PAYROLL_DATE AND 
     DR.DISBURSEMENT_STATUS_VALUE <> 'CANL' 

    GROUP BY 
     PA.PERSON_ID, PA.PERSON_ACCOUNT_ID, DR.DISBURSEMENT_REQUEST_ID, DD.PRE_TAX_AMOUNT, DD.PRE_TAX_AMOUNT, DD.POST_TAX_AMOUNT 
     ) as x 
where x.ct = 1 
0

Я бы материализовать это в #temp

SELECT DR1.PERSON_ACCOUNT_ID, SDD1.DETAIL_CATEGORY_VALUE 
    FROM SGT_DISBURSEMENT_REQUEST SDR1 
    JOIN SGT_DISBURSEMENT_DETAIL SDD1 
     ON SDD1.DISBURSEMENT_REQUEST_ID = SDR1.DISBURSEMENT_REQUEST_ID 
GROUP BY SDR1.PERSON_ACCOUNT_ID, SDD1.DETAIL_CATEGORY_VALUE 
HAVING COUNT(*) = 1 

join #temp 
     on #temp.PERSON_ACCOUNT_ID = DR.PERSON_ACCOUNT_ID 
    and #temp.DETAIL_CATEGORY_VALUE = DD.DETAIL_CATEGORY_VALUE 
Смежные вопросы