2016-09-16 2 views
1
WHERE 
AND NOT EXISTS 
     (SELECT cl.userID 
     FROM campaign_list cl 
     WHERE cl.userID = customer_profile.userID 
     AND (cl.notes = 'report12' or cl.notes = 'report16') 
     ) 
    AND EXISTS 
     (SELECT cl.userID 
     FROM campaign_list cl 
     WHERE cl.userID = customer_profile.userID 
     AND cl.notes = 'report11' 
     ) 
    AND 
     (SELECT max(cl.send_date) 
      FROM campaign_list cl 
      WHERE cl.userID = customer_profile.userID 
      AND cl.notes = 'report11' 
     ) > lastSuccessfulDepositDate 

약 20 초 후에 쿼리가 실행됩니다. 그러나 위의 행은 실행하는 데 약 3 분이 걸립니다.수식 속도가 느려집니다. 이 줄이없는

캠페인 목록은 겨우 3,700 개의 행이지만 천천히 꾸준히 증가하고 있습니다. 이 쿼리를 빠르게하기위한 조언이 있습니까?

+0

개별적으로 3 번 시도해 보셨습니까? 특히 어떤 사람이 더 많은 부정적인 영향을 미치는 것 같습니까? –

+0

얼마나 많은 행이 반환됩니까? "기본 테이블"에 몇 개의 행이 있습니까? (여기에 언급되지 않은 lastsuccessfuldepositdate가 포함 된 여기에 언급되지 않은 주소 캠페인 목록에있는 행의 수 –

+0

존재하지 않음 = 2:10, 존재 = 1:55, 최대 (send_date) = 1:52 – eddd83

답변

0

확인 campiaign_list 확인은 사용자 ID에 인덱스를 가지고 있으며,

당신 만 추가 인덱스 기능 인덱스를 사용할 수있는 노트 때 메모 = 'report16'또는 'report11'하지만 나 시스템과 좋은하지 않을 수 있습니다 전체.

또한 같은 인덱스에 SEND_DATE을 포함 할 수 있습니다 ...

create index on campaign_list (notes, user_id, send_date) 

또한, 그것은에서 선택 *을 할 빠르게 아주 소폭의 당신의 열 이름을 선택하는 대신 쿼리를 존재한다.

또 다른 예 : 이 campaign_list (SEND_DATE)에 인덱스를 만들 경우 메모 = 'report11'

+0

userid가 기본 키입니다.notes 및 send_date에 중복 값이 ​​있습니다. 따라서 "max (send_date)"를 사용하는 이유. 인덱스를 만들면 임시 또는 영구적입니까? (일명 데이터베이스에 항목을 추가 할 수있는 기능이 없습니다) – eddd83

+0

적어도 기능적 또는 부분적인 인덱스를 사용하는 것이 좋습니다 –

1

수행하면 다음과 같은 인덱스가 : campaign_list(userID, notes, send_date)를? 이것은 세 개의 부속 조회에 대한 최적 색인입니다.

그런 다음 각 조건을 별도로 시도 했습니까? 즉, 각자 1 분이 걸릴지 아십니까? 또는, 00:02:59와 다른 두 개의 00:00:01을 사용합니까?

, 당신은이 두 가지에 대한 세 가지 조건을 단순화 할 수 있습니다

WHERE 
AND NOT EXISTS 
     (SELECT cl.userID 
     FROM campaign_list cl 
     WHERE cl.userID = customer_profile.userID AND 
       cl.notes IN ('report12', cl.notes = 'report16') 
     ) 
    AND EXISTS 
     (SELECT cl.userID 
     FROM campaign_list cl 
     WHERE cl.userID = customer_profile.userID AND 
       cl.notes = 'report11' and 
       cl.send_date > ?.lastSuccessfulDepositDate 
     ) 

같은 지수는 여기에 적용됩니다.

참고 : in은이 경우 성능에 실제로 영향을 미치지 않지만 쓰기 및 읽기가 더 쉽습니다.

+0

userid가 기본 키입니다. notes 및 send_date에 중복 값이 ​​있습니다. 따라서 "max (send_date)"를 사용하는 이유는 – eddd83

+0

은 brin 인덱스를 사용하는 것이 좋지만 중복 값은 문제가되지 않습니다. 색인은 고유하지 않아도되며 고유하지 않아도됩니다. 내가 말한 것을 시도해보고 결과를 게시하십시오 ... 때로는 시행 착오가 사물을 overthinking. –

+0

userid가 무엇의 기본 키입니까? 내가 제안하는 인덱스는 customer_profile에 없지만 campaign_list에 있습니다. 물론 중복 값이 ​​있으며 campaign_list 테이블의 campaign_list –

0

각각의 테이블, "IN"당신에게 더 나은 결과를 제공 할 수 있습니다 "NOT IN"의 행의 수에 따라 (또한 컴퓨터의 구성 및 메모리에 따라 다름)

예 :

where 
customer_profile.userID not in 
(
    (SELECT cl.userID 
    FROM campaign_list cl 
    WHERE cl.notes not in ('report12','report16') 
    [perhaps some other predicate here that's also in the main query] 
    ) 
)... 

각 테이블의 행 수를 알면 도움이 될 것입니다

+0

주 테이블 (일명 FROM)은 고객 프로필 테이블입니다 : 143,604 rows. 캠페인 목록은 단지 3,308 행입니다. – eddd83

+0

필자가 제안한 "in"및 "not in"쿼리를 사용하는 것이 더 좋을 수도 있습니다. 그 이유는 143K 시간 대신 한 번만 campaign_list 테이블을 통과해야하기 때문입니다. 특히 노트를 인덱싱하고 싶지 않으므로 또는 날짜 ... –

관련 문제