빠른

2016-11-02 4 views
0

을이 느린 중첩 된 SQL 케이스 쿼리를 만들기 위해 어떻게 DOB 등 나는 또한이 포함이의 SQL보기를 만들려고하고빠른

을 이름, 성, 같은 필드를 포함 '연락처'의 테이블이 필드는 'ProspectiveNews'라고합니다. 이 필드는 본질적으로 다른보기의 기준에 일치하는 4 개의 분류 코드 (또는 공란) 중 하나를 포함합니다.

연락처에는 다른 YearLevels가있는이 다른보기에서 많은 레코드가있을 수 있습니다. 이 다른보기에서

는 연락처 ID 한 두 열에 표시 할 수 : [연락처 ID] 또는 [ContactSpouseID] 여기서 다른 열 ReferenceTable <> '문의'

그렇다면 어떤 레코드가 어디 ReferenceTable = '문의 'ContactID 열에 EnquiryID가 포함되어있어이를 사용해야합니다.

따라서 3 개는 각 분류 코드를 확인합니다.

코드는 이지만 실행하려면 약 2 분이 걸립니다. 문제는 너무 느립니다. 더 빨리이 작업을 수행하려면 어떻게해야합니까?

코드 요약 :

연락 (이다) 또 다른보기에서 레코드 (들)가있는 경우에만 YearLevel 0 THEN 서로 'K'연락 레코드 (들)가있는 경우

(있습니다)입니다 만보기 YearLevel 1-6 THEN '1-6'

연락 레코드 (들) (이다) 또 다른보기를 형성이있는 경우 YearLevel 7-12 THEN '7-12'

IF 연락처에 YearLevels에있는 레코드가있는 경우 :

0과 1-6

또는

0과 7 ~ 12

또는

1-6 및 7-12

THEN '일반'

코드 :

엔진이 경이를해야하는 하위 쿼리를 최적화 할 수 있도록 인덱스를 생성 16,

SELECT 
 

 
C.ID as ContactID, 
 
ESC.ID as EnquiryID, 
 

 
CASE WHEN \t (\t C.ID in \t \t (SELECT [ContactID] FROM [Table] WHERE [EnrolDate] > '2016-12-31' AND YearLevel = 0 AND ReferenceTable <> 'Enquiry') 
 
\t \t \t AND NOT EXISTS \t (SELECT [ContactID] FROM [Table] WHERE [EnrolDate] > '2016-12-31' AND YearLevel > 0 AND ReferenceTable <> 'Enquiry' AND [ContactID] = C.ID) 
 
\t \t \t) 
 
\t \t \t OR 
 
\t \t \t (\t C.ID in \t \t (SELECT [ContactSpouseID] FROM [Table] WHERE [EnrolDate] > '2016-12-31' AND YearLevel = 0 AND ReferenceTable <> 'Enquiry') 
 
\t \t \t AND NOT EXISTS \t (SELECT [ContactSpouseID] FROM [Table] WHERE [EnrolDate] > '2016-12-31' AND YearLevel > 0 AND ReferenceTable <> 'Enquiry' AND [ContactSpouseID] = C.ID) 
 
\t \t \t) 
 
\t \t \t OR 
 
\t \t \t (\t ESC.ContactEnquiryID in \t \t (SELECT [ContactID] FROM [Table] WHERE [EnrolDate] > '2016-12-31' AND YearLevel = 0 AND ReferenceTable = 'Enquiry') 
 
\t \t \t AND NOT EXISTS (SELECT [ContactID] FROM [Table] WHERE [EnrolDate] > '2016-12-31' AND YearLevel > 0 AND ReferenceTable = 'Enquiry' AND [ContactID] = C.ID) 
 
\t \t \t) 
 
THEN 'K' 
 

 
ELSE 
 

 
CASE WHEN \t (\t C.ID in \t \t (SELECT [ContactID] FROM [Table] WHERE [EnrolDate] > '2016-12-31' AND YearLevel > 0 AND YearLevel < 7 AND ReferenceTable <> 'Enquiry') 
 
\t \t \t AND NOT EXISTS \t (SELECT [ContactID] FROM [Table] WHERE [EnrolDate] > '2016-12-31' AND YearLevel = 0 AND ReferenceTable <> 'Enquiry' AND [ContactID] = C.ID) 
 
\t \t \t AND NOT EXISTS \t (SELECT [ContactID] FROM [Table] WHERE [EnrolDate] > '2016-12-31' AND YearLevel > 6 AND ReferenceTable <> 'Enquiry' AND [ContactID] = C.ID) 
 
\t \t \t) 
 
\t \t \t OR 
 
\t \t \t (\t C.ID in \t \t (SELECT [ContactSpouseID] FROM [Table] WHERE [EnrolDate] > '2016-12-31' AND YearLevel > 0 AND YearLevel < 7 AND ReferenceTable <> 'Enquiry') 
 
\t \t \t AND NOT EXISTS \t (SELECT [ContactSpouseID] FROM [Table] WHERE [EnrolDate] > '2016-12-31' AND YearLevel = 0 AND ReferenceTable <> 'Enquiry' AND [ContactSpouseID] = C.ID) 
 
\t \t \t AND NOT EXISTS \t (SELECT [ContactSpouseID] FROM [Table] WHERE [EnrolDate] > '2016-12-31' AND YearLevel > 6 AND ReferenceTable <> 'Enquiry' AND [ContactSpouseID] = C.ID) 
 
\t \t \t) 
 
\t \t \t OR 
 
\t \t \t (\t ESC.ContactEnquiryID in \t \t (SELECT [ContactID] FROM [Table] WHERE [EnrolDate] > '2016-12-31' AND YearLevel > 0 AND YearLevel < 7 AND ReferenceTable = 'Enquiry') 
 
\t \t \t AND NOT EXISTS \t (SELECT [ContactID] FROM [Table] WHERE [EnrolDate] > '2016-12-31' AND YearLevel = 0 AND ReferenceTable = 'Enquiry' AND [ContactID] = C.ID) 
 
\t \t \t AND NOT EXISTS \t (SELECT [ContactID] FROM [Table] WHERE [EnrolDate] > '2016-12-31' AND YearLevel > 6 AND ReferenceTable = 'Enquiry' AND [ContactID] = C.ID) 
 
\t \t \t) 
 
\t \t \t 
 
THEN '1-6' 
 

 
    ELSE 
 

 
CASE WHEN \t (\t C.ID in \t \t (SELECT [ContactID] FROM [Table] WHERE [EnrolDate] > '2016-12-31' AND YearLevel > 6 AND YearLevel < 13 AND ReferenceTable <> 'Enquiry') 
 
\t \t \t AND NOT EXISTS \t (SELECT [ContactID] FROM [Table] WHERE [EnrolDate] > '2016-12-31' AND YearLevel < 7 AND ReferenceTable <> 'Enquiry' AND [ContactID] = C.ID) 
 
\t \t \t) 
 
\t \t \t OR 
 
\t \t \t (\t C.ID in \t \t (SELECT [ContactSpouseID] FROM [Table] WHERE [EnrolDate] > '2016-12-31' AND YearLevel > 6 AND YearLevel < 13 AND ReferenceTable <> 'Enquiry') 
 
\t \t \t AND NOT EXISTS \t (SELECT [ContactSpouseID] FROM [Table] WHERE [EnrolDate] > '2016-12-31' AND YearLevel < 7 AND ReferenceTable <> 'Enquiry' AND [ContactSpouseID] = C.ID) 
 
\t \t \t) 
 
\t \t \t OR 
 
\t \t \t (\t ESC.ContactEnquiryID in \t \t (SELECT [ContactSpouseID] FROM [Table] WHERE [EnrolDate] > '2016-12-31' AND YearLevel > 6 AND YearLevel < 13 AND ReferenceTable = 'Enquiry') 
 
\t \t \t AND NOT EXISTS \t (SELECT [ContactSpouseID] FROM [Table] WHERE [EnrolDate] > '2016-12-31' AND YearLevel < 7 AND ReferenceTable = 'Enquiry' AND [ContactID] = C.ID) 
 
\t \t \t) 
 
THEN '7-6' 
 

 
    ELSE 
 

 
CASE WHEN \t (\t C.ID in \t \t (SELECT [ContactID] FROM [Table] WHERE [EnrolDate] > '2016-12-31' AND ReferenceTable <> 'Enquiry') 
 
\t \t \t) 
 
\t \t \t OR 
 
\t \t \t (\t C.ID in \t \t (SELECT [ContactSpouseID] FROM [Table] WHERE [EnrolDate] > '2016-12-31' AND ReferenceTable <> 'Enquiry') 
 
\t \t \t) 
 
\t \t \t OR 
 
\t \t \t (\t ESC.ContactEnquiryID in \t \t (SELECT [ContactID] FROM [Table] WHERE [EnrolDate] > '2016-12-31' AND ReferenceTable = 'Enquiry') 
 
\t \t \t) 
 

 
THEN 'General' 
 

 
    ELSE '' END END 
 

 
\t END 
 
END AS ProspectiveNews

+0

성능이 저하되는 이유는 [Table]에서 너무 많이 선택하기 때문입니다. 대신 [table]의 후보 목록에 가입하고, 아마도 집계하고, 결합 된 필드를 사용하여 사례를 사용하십시오. 시간이 있으면 나중에 예제를 쓸 것입니다. OUTER APPLY를 사용하고자하는 메인 테이블을 참조하기 위해 가입해야 할 필요가 있다면 Itzik Ben-Gan의 게시물을 보거나 여기를보십시오. https://sqlbits.com/Sessions/Event14/Boost_your_T-SQL_with_the_APPLY_Operator –

+0

감사합니다. 정보. 나중에 시간이 있으면 예제를보고 싶습니다. 나는 이것에 대해서만 새로운 것이다. – SSS

+0

스키마 정보를 추가 할 수 있습니까? C, ESC와 [Table]의 관계는 무엇입니까? –

답변

0

@UV

감사합니다 : 느린 성능은 [표] 너무 여러 번에서 선택되는 사실에 기인한다. 대신 [table]의 후보 목록에 가입하고, 아마도 집계하고, 결합 된 필드를 사용하여 사례를 사용하십시오. 시간이 있으면 나중에 예제를 쓸 것입니다.OUTER APPLY를 사용하고자하는 메인 테이블을 참조 할 필요가 있다면 Itzik Ben-Gan의 좋은 글이 여기에 있습니다 : sqlbits.com/Sessions/Event14/... - UV

0

. 이러한 여러 인덱스를 만드는 시도해야합니다 :

+0

정보를 제공해 주셔서 감사합니다. 나는 지금까지 '색인'에 대해 들어 본 적이 없다. 이 코드에이 코드를 추가합니까, 아니면 다른 코드를 작성해야합니까? – SSS

+0

예, 별개입니다. SQL Server Management Studio로 이동하여 테이블의 디자인 페이지를 입력하십시오. 일단 거기, 오른쪽 단추 메뉴에는 색인/열쇠 선택권이있을 것이다. 그런 다음 해당 인덱스를 추가하기 만하면됩니다 (각 인덱스는 쿼리를 완벽하게 최적화 할 수 있도록 Columns 속성에 여러 필드가 있어야 함을 기억하십시오). –

+0

색인이 도움이 될 수 있지만 해결책이 아니어야합니다. 색인이 너무 많으면 전반적인 성능이 저하 될 수 있습니다. 모든 성능 문제는 먼저 서버 구성을 변경하기 전에 쿼리를 최적화해야합니다. –

0

느린 성능 [Table]에서 너무 많이 선택하고 있기 때문입니다. 대신 [table]의 후보 목록에 가입하고, 아마도 집계하고, 결합 된 필드를 사용하여 사례를 사용하십시오. 시간이 있으면 나중에 예제를 쓸 것입니다. OUTER APPLY를 사용하고자하는 메인 테이블을 참조하기 위해 Join이 필요하면 itzik Ben-Gan의 좋은 글이 여기에 있습니다 : sqlbits.com/Sessions/Event14/... - UV

Tahnk you @ SSS