2015-01-27 2 views
0

실행할 시간을두고있는 두 개의 쿼리를 상속했습니다. 테이블에 약 5 천만 개의 행이 있으며 인덱스가 없습니다. 후자는 수정 될 것이며 의심의 여지가 성능을 향상시킬 것입니다,하지만 이것들을보다 효율적으로 만드는 것에 대한 빠른 제안은 무엇입니까?TSQL 쿼리 개선

Update OP_working 
Set Is_fertility = 
(case 
when PRIMARY_DIAGNOSIS_CODE_CLND in (select ICD10 from dbo.CH_ref_fertility_ICD10) 
or SECONDARY_DIAGNOSIS_CODE_1_CLND IN (select ICD10 from dbo.CH_ref_fertility_ICD10) 
or SECONDARY_DIAGNOSIS_CODE_2_CLND IN (select ICD10 from dbo.CH_ref_fertility_ICD10) 
or SECONDARY_DIAGNOSIS_CODE_3_CLND IN (select ICD10 from dbo.CH_ref_fertility_ICD10) 
or SECONDARY_DIAGNOSIS_CODE_4_CLND IN (select ICD10 from dbo.CH_ref_fertility_ICD10) 
or SECONDARY_DIAGNOSIS_CODE_5_CLND IN (select ICD10 from dbo.CH_ref_fertility_ICD10) 
or SECONDARY_DIAGNOSIS_CODE_6_CLND IN (select ICD10 from dbo.CH_ref_fertility_ICD10) 
or SECONDARY_DIAGNOSIS_CODE_7_CLND IN (select ICD10 from dbo.CH_ref_fertility_ICD10) 
or SECONDARY_DIAGNOSIS_CODE_8_CLND IN (select ICD10 from dbo.CH_ref_fertility_ICD10) 
or SECONDARY_DIAGNOSIS_CODE_9_CLND IN (select ICD10 from dbo.CH_ref_fertility_ICD10) 
or SECONDARY_DIAGNOSIS_CODE_10_CLND IN (select ICD10 from dbo.CH_ref_fertility_ICD10) 
or SECONDARY_DIAGNOSIS_CODE_11_CLND IN (select ICD10 from dbo.CH_ref_fertility_ICD10) 
or SECONDARY_DIAGNOSIS_CODE_12_CLND IN (select ICD10 from dbo.CH_ref_fertility_ICD10) 
then '1' 

when PRIMARY_PROCEDURE_CODE in (select OPCS from dbo.CH_ref_fertility_OPCS) 
OR SECONDARY_PROCEDURE_CODE_1 IN (select OPCS from dbo.CH_ref_fertility_OPCS) 
OR SECONDARY_PROCEDURE_CODE_2 IN (select OPCS from dbo.CH_ref_fertility_OPCS) 
OR SECONDARY_PROCEDURE_CODE_3 IN (select OPCS from dbo.CH_ref_fertility_OPCS) 
OR SECONDARY_PROCEDURE_CODE_4 IN (select OPCS from dbo.CH_ref_fertility_OPCS) 
OR SECONDARY_PROCEDURE_CODE_5 IN (select OPCS from dbo.CH_ref_fertility_OPCS) 
OR SECONDARY_PROCEDURE_CODE_6 IN (select OPCS from dbo.CH_ref_fertility_OPCS) 
OR SECONDARY_PROCEDURE_CODE_7 IN (select OPCS from dbo.CH_ref_fertility_OPCS) 
OR SECONDARY_PROCEDURE_CODE_8 IN (select OPCS from dbo.CH_ref_fertility_OPCS) 
OR SECONDARY_PROCEDURE_CODE_9 IN (select OPCS from dbo.CH_ref_fertility_OPCS) 
OR SECONDARY_PROCEDURE_CODE_10 IN (select OPCS from dbo.CH_ref_fertility_OPCS) 
OR SECONDARY_PROCEDURE_CODE_11 IN (select OPCS from dbo.CH_ref_fertility_OPCS) 
then '1' 
else '0' 
end 
) 

update OP_working 
set derived_commissioner = 
(case 
when derived_commissioner_type = 'Private/Chargeable OSV' then 'VPP00' 
when derived_commissioner_type = 'CCG_of_practise' and GP_PRACTICE_CODE not in(select GP_PRACTICE_CODE from dbo.CH_ref_practise_codes)then 'CCG_of_practise - unknown' 
when derived_commissioner_type = 'CCG_of_practise' then (select [PARENT_CODE] from dbo.CH_ref_practise_codes where OP_working.GP_PRACTICE_CODE = CH_ref_practise_codes.GP_PRACTICE_CODE)--+' - '+derived_commissioner 
when derived_commissioner_type = 'AT_of_Provider' and provider_code not in (select provider_code from CH_ref_provider_codes) then 'AT_of_Provider - Unknown' 
when derived_commissioner_type = 'AT_of_Provider' then (select Commissioning_AT from dbo.CH_ref_provider_codes where OP_working.provider_code = CH_ref_provider_codes.ORG_CODE)--+' - '+derived_commissioner 
when derived_commissioner_type = 'Commissioning_AT_of_prison' and GP_PRACTICE_CODE not in (select GP_PRACTICE_CODE from CH_ref_prison_practises) then 'Commissioning_AT_of_prison - Unknown' 
when derived_commissioner_type = 'Commissioning_AT_of_prison' then (select [HUB_CODE] from dbo.CH_ref_prison_practises where OP_working.GP_PRACTICE_CODE = CH_ref_prison_practises.GP_PRACTICE_CODE)--+' - '+derived_commissioner 
when derived_commissioner_type = 'Dental - AT_of_CCG' and GP_PRACTICE_CODE not in (select GP_PRACTICE_CODE from dbo.CH_ref_practise_codes) then 'AT_of_CCG - Unknown' 
when derived_commissioner_type = 'Dental - AT_of_CCG' then (select [AREA_TEAM_CODE] from dbo.CH_ref_practise_codes where OP_working.GP_PRACTICE_CODE = CH_ref_practise_codes.GP_PRACTICE_CODE)--+' - '+derived_commissioner 
when derived_commissioner_type = 'AT_of_CCG' and GP_PRACTICE_CODE not in (select GP_PRACTICE_CODE from dbo.CH_ref_practise_codes) then 'AT_of_CCG - Unknown' 
when derived_commissioner_type = 'AT_of_CCG' then (select [AREA_TEAM_CODE] from dbo.CH_ref_practise_codes where OP_working.GP_PRACTICE_CODE = CH_ref_practise_codes.GP_PRACTICE_CODE)--+' - '+derived_commissioner 
when derived_commissioner_type = 'Wales' then (select [PARENT_CODE] from dbo.CH_ref_practise_codes where OP_working.GP_PRACTICE_CODE = CH_ref_practise_codes.GP_PRACTICE_CODE)--+' - '+derived_commissioner 


else derived_commissioner_type 
end) 

나는 모든 "에서 선택"보다는 조인을 고려하지만, 단지 우선 몇 가지 의견을 원했다.

SQL Server 버전도 2012입니다.

+0

진술은 읽기 쉽지 않습니다. 첫 번째 문장은 조인과 함께 훨씬 더 깨끗해질 것입니다. 둘째, 다른 값이 너무 많으면 참조 테이블에 넣고 OP_Working과 결합하여 적절한 값을 설정하십시오 –

+0

SQL에서 많은 비즈니스 로직을 수행하고있는 것처럼 보입니다. 가능한 경우 비즈니스 로직 계층으로 이동하고 SQL을 단순화합니다. –

+0

R 일 - 이것은 데이터가로드 될 때 매월 실행되는 순전히 데이터 크런치 루틴입니다. SQL이있는 프로 시저를 호출하는 SSIS 패키지 이외의 다른 계층은 없습니다. – Raymondo

답변

0

직접 테스트하지 않는 한 아무도 최선의 방법을 말할 수 없습니다. 나는이 같은이 사용하는 임시 테이블을 할 것입니다 :

DECLARE @ICD10 TABLE (ID INT) 
DECLARE @OPCS TABLE (ID INT) 

INSERT INTO @ICD10 
     SELECT ICD10 
     FROM dbo.CH_ref_fertility_ICD10 

INSERT INTO @OPCS 
     SELECT OPCS 
     FROM dbo.CH_ref_fertility_OPCS 

UPDATE OP_working 
SET  Is_fertility = 0 

UPDATE w 
SET  Is_fertility = 1 
FROM OP_working w 
     JOIN @ICD10 t ON t.ID = PRIMARY_DIAGNOSIS_CODE_CLND 
         OR t.ID = SECONDARY_DIAGNOSIS_CODE_1_CLND 
         OR t.ID = SECONDARY_DIAGNOSIS_CODE_2_CLND 
         OR t.ID = SECONDARY_DIAGNOSIS_CODE_3_CLND 
         OR t.ID = SECONDARY_DIAGNOSIS_CODE_4_CLND 
         OR t.ID = SECONDARY_DIAGNOSIS_CODE_5_CLND 
         OR t.ID = SECONDARY_DIAGNOSIS_CODE_6_CLND 
         OR t.ID = SECONDARY_DIAGNOSIS_CODE_7_CLND 
         OR t.ID = SECONDARY_DIAGNOSIS_CODE_8_CLND 
         OR t.ID = SECONDARY_DIAGNOSIS_CODE_9_CLND 
         OR t.ID = SECONDARY_DIAGNOSIS_CODE_10_CLND 
         OR t.ID = SECONDARY_DIAGNOSIS_CODE_11_CLND 
         OR t.ID = SECONDARY_DIAGNOSIS_CODE_12_CLND 

UPDATE w 
SET  Is_fertility = 1 
FROM OP_working w 
     JOIN @OPCS t ON t.ID = PRIMARY_PROCEDURE_CODE 
         OR t.ID = SECONDARY_PROCEDURE_CODE_1 
         OR t.ID = SECONDARY_PROCEDURE_CODE_2 
         OR t.ID = SECONDARY_PROCEDURE_CODE_3 
         OR t.ID = SECONDARY_PROCEDURE_CODE_4 
         OR t.ID = SECONDARY_PROCEDURE_CODE_5 
         OR t.ID = SECONDARY_PROCEDURE_CODE_6 
         OR t.ID = SECONDARY_PROCEDURE_CODE_7 
         OR t.ID = SECONDARY_PROCEDURE_CODE_8 
         OR t.ID = SECONDARY_PROCEDURE_CODE_9 
         OR t.ID = SECONDARY_PROCEDURE_CODE_10 
         OR t.ID = SECONDARY_PROCEDURE_CODE_11 

은 무엇 두 번째 문에 대해, 그것을 시도하는 복잡한이다를 최적화 할 수 있습니다. 사례를 다른 업데이트 문으로 분리 해보십시오.

+0

감사합니다. Giorgi/Clausen, 나는 테스트와 연주가 유일한 실제 방법이라는 귀하의 의견 Giorgi에 완전히 동의합니다. 문제는 분석가가 지난 밤에 일련의 쿼리를 해고했기 때문에 서버가 그것을 망치고있다 (라이브 서버이기 때문에 쿼리를 중단하고 싶지 않았다). 그리고 오늘날 나의 뇌가 ' 일하고 싶지 않아서, 게으른 모드로 비정상적으로 물었다. 두 번 째 진술에 합의하면 여러 진술을하는 것이 더 현명한 방법이 될 것입니다. 중대한 응답 녀석 및 그들은 생각을위한 나의 "아니오 쇼"두뇌 음식을 주었다 – Raymondo

0

대신이 시도

감사 :

UPDATE t1 
SET Is_fertility = coalesce(t2.x, t3.x, 0) 
FROM OP_working t1 
OUTER APPLY 
(SELECT top 1 1 x 
FROM dbo.CH_ref_fertility_ICD10 
WHERE ICD10 IN 
    (t1.PRIMARY_DIAGNOSIS_CODE_CLND, t1.SECONDARY_DIAGNOSIS_CODE_1_CLND, 
    t1.SECONDARY_DIAGNOSIS_CODE_2_CLND, t1.SECONDARY_DIAGNOSIS_CODE_3_CLND, 
    t1.SECONDARY_DIAGNOSIS_CODE_4_CLND, t1.SECONDARY_DIAGNOSIS_CODE_5_CLND, 
    t1.SECONDARY_DIAGNOSIS_CODE_6_CLND, t1.SECONDARY_DIAGNOSIS_CODE_7_CLND, 
    t1.SECONDARY_DIAGNOSIS_CODE_8_CLND, t1.SECONDARY_DIAGNOSIS_CODE_9_CLND, 
    t1.SECONDARY_DIAGNOSIS_CODE_10_CLND, t1.SECONDARY_DIAGNOSIS_CODE_11_CLND, 
    t1.SECONDARY_DIAGNOSIS_CODE_12_CLND) 
ORDER BY (SELECT 1) 
) t2 
OUTER APPLY 
(SELECT top 1 1 x 
FROM dbo.CH_ref_fertility_OPCS 
WHERE OPCS IN 
    (t1.PRIMARY_PROCEDURE_CODE, t1.SECONDARY_PROCEDURE_CODE_1, 
    t1.SECONDARY_PROCEDURE_CODE_2, t1.SECONDARY_PROCEDURE_CODE_3, 
    t1.SECONDARY_PROCEDURE_CODE_4, t1.SECONDARY_PROCEDURE_CODE_5, 
    t1.SECONDARY_PROCEDURE_CODE_6, t1.SECONDARY_PROCEDURE_CODE_7, 
    t1.SECONDARY_PROCEDURE_CODE_8, t1.SECONDARY_PROCEDURE_CODE_9, 
    t1.SECONDARY_PROCEDURE_CODE_10, t1.SECONDARY_PROCEDURE_CODE_11) 
ORDER BY (SELECT 1) 
) t3 

이 50 만 개 달러 행이 작동하지만 나는 그것이 현재 스크립트보다 빠르게 생각하지 확인합니다. 죄송합니다. 2 부로 시도하지 않을 것입니다.