2017-10-15 6 views
0

이 MySQL 쿼리를 최적화하려고합니다. 현재 약속을보기 전에 약속이없는 고객 수를 계산하고 싶습니다. 즉, if 그들은 약속을 가지고 있는데 (부질의가 검사하는 것임), 제외시킨다.MySQL을 최적화하지 않음 (쿼리

그러나이 쿼리는 절대적으로 성능을 떨어 뜨린다. 나는 MySQL이 NOT IN (질의, 나는이 쿼리를 최적화에 대해 갈 수있는 가장 좋은 방법에 확실하지 않다. 내가의 CustNo, AptStatus 및 AptNum에 인덱스를 만들었습니다. 실행하는 데 15 ~ 30 초 간 걸립니다.

SELECT 
     COUNT(*)    AS NumOfCustomersWithPriorAppointment, 
FROM 
     transaction_log AS tl 
LEFT JOIN 
     appointment AS a 
ON 
     a.AptNum = tl.AptNum 
INNER JOIN 
     customer AS c 
ON 
     c.CustNo = tl.CustNo 
WHERE 
     a.AptStatus IN (2) 
AND  a.CustNo NOT IN 
     (
       SELECT 
         a2.CustNo 
       FROM 
         appointment a2 
       WHERE 
         a2.AptDateTime < a.AptDateTime) 


AND  a.AptDateTime > BEGIN_QUERY_DATE 
AND  a.AptDateTime < END_QUERY_DATE 

미리 감사드립니다.

+0

쿼리의 각 테이블에 대해 'SHOW CREATE TABLE' 문을 제공하십시오. –

+0

'BEGIN_QUERY_DATE '는 (는) 상수입니까? 아니면 다른 컬럼? 'LEFT JOIN .. IS NULL'을 사용하여 쿼리를 다시 작성하십시오. 그것이 더 빠를 지 말해주십시오. –

+0

덧붙여서, 외부 조인 (a)은 실제로 내부 조인입니다. – Strawberry

답변

0

는 다음과 같은 시도 :

SELECT 
     COUNT(*)    AS NumOfCustomersWithPriorAppointment, 
FROM 
     transaction_log AS tl 
INNER JOIN 
     appointment AS a 
ON 
     a.AptNum = tl.AptNum 
LEFT OUTER JOIN appointment AS earlier_a 
     ON earlier_a.CustNo = a.CustNo 
     AND earlier_a.AptDateTime < a.AptDateTime 
INNER JOIN 
     customer AS c 
ON 
     c.CustNo = tl.CustNo 
WHERE 
     a.AptStatus IN (2) 
AND  earlier_a.AptNum IS NULL 


AND  a.AptDateTime > BEGIN_QUERY_DATE 
AND  a.AptDateTime < END_QUERY_DATE 

이는 (CustNo,AptDateTime)에 복합 인덱스 도움이됩니다. 귀하의 비즈니스 모델에 맞으면 고유하게 만드십시오 (논리적으로는 응용 프로그램의 충돌을 처리하는 방법에 따라 논리적으로는 가능하지만 사실상 그렇지 않을 수 있습니다.)

이렇게하면 모든 테이블에 대해 SHOW CREATE TABLE 문을 제공합니다. 충분한 성능 향상.

+0

이 쿼리는 정확히 내버려 뒀습니다. 귀하의 도움과 제안에 진심으로 감사드립니다! – 3C41DC