쿼리 NOT EXISTS 속도 문의 드립니다. 0 8 1,179

by 박준수 [2019.08.06 14:51:23]


안녕하세요 속도 질문 드립니다.

MYSQL을 사용중인데요 

아래 쿼리를 실행시키면 10분이상 걸려서 개선할 수 있는 방법을 여쭤봅니다.

NOT EXISTS 위로는 문제없이 잘 실행되는데요 

NOT EXISTS 해당 쿼리를 포함해서 실행하면 너무 오래걸리는데 이게 혹시 데이터 건수문제인지

인덱스나 별도 다른 문제인지 쿼리가 잘못된건지 질문드려요 이렇게 비교할 때는 다른 방법은 떠오르지는 않아서요 ..

혹시 몰라서 맨 아래 테이블 컬럼도 첨부합니다.

SELECT count(*)
  FROM tn_mer a 
     INNER JOIN tn_mer_pan b 
         ON a.mer_sn=b.mer_sn 
 WHERE 1=1 
       AND a.member ='N' 
       AND ifnull(a.email_yn, 'Y') = 'Y' 
       AND b.pan_secsn = 'N' 
       AND b.birth < ((YEAR(NOW())-14)+1) 
       AND NOT EXISTS 
       (SELECT * 
         FROM tn_only_result s1 
        WHERE a.mer_sn = s1.mer_sn 
              AND s1.only_sn = 180 
       ) ;

 

 

-- 31140 건

TABLE `tn_mer` (
  `mer_sn` bigint(20) NOT NULL AUTO_INCREMENT ,
  `mer_id` varchar(50) NOT NULL,
  `passwd` varchar(100) NOT NULL,
  `mtlnum` varchar(20) NOT NULL,
  `creat_dttm` datetime NOT NULL,
  `updt_dttm` datetime NOT NULL,
  `login_dttm` datetime DEFAULT NULL,
  `visit` bigint(20) NOT NULL DEFAULT '0' COMMENT '방문 수',
  `mngr_dc` mediumtext,
  `secsn` char(1) NOT NULL DEFAULT 'N',
  `secsn_dt` datetime DEFAULT NULL,
  `sms_yn` varchar(1) DEFAULT 'Y',
  `email_yn` varchar(1) DEFAULT 'Y',
  `recommender` varchar(50) DEFAULT NULL,
  `member` char(1) NOT NULL DEFAULT 'N',
  `vySn` int(11) DEFAULT NULL,
  PRIMARY KEY (`mer_sn`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

-- 15853건
TABLE `tn_mer_pan` (
  `mer_sn` bigint(20) NOT NULL DEFAULT '0',
  `pan_grad` bigint(20) NOT NULL DEFAULT '0',
  `dnc_code` bigint(20) NOT NULL DEFAULT '0',
  `birth` int(11) NOT NULL DEFAULT '0',
  `sexdstn` varchar(1) NOT NULL,
  `cp_code` bigint(20) NOT NULL DEFAULT '0',
  `pan_secsn` char(1) NOT NULL DEFAULT 'N',
  `pan_secsn_dt` datetime DEFAULT NULL ,
  `gion_code` bigint(20) NOT NULL DEFAULT '0',
  `acmcr_code` bigint(20) NOT NULL DEFAULT '0',
  `inn_code` bigint(20) NOT NULL DEFAULT '0',
  `join_code` bigint(20) NOT NULL DEFAULT '0',  
  PRIMARY KEY (`mer_sn`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- 112842
TABLE `tn_only_result` (
  `only_result_sn` bigint(20) NOT NULL AUTO_INCREMENT ,
  `only_sn` bigint(20) NOT NULL DEFAULT '0',
  `mer_sn` bigint(20) NOT NULL DEFAULT '0',
  `creat_dt` datetime NOT NULL,
  `creat_ip` varchar(15) DEFAULT NULL,
  PRIMARY KEY (`only_result_sn`,`only_sn`,`mer_sn`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

 

 

 

by 박준수 [2019.08.06 15:35:54]

only_sn 해당 데이터는 3개로 pk 가 묶여 있어서

한개가 아니에요 대략 4만개 정도입니다.
 


by 생각 [2019.08.07 08:57:37]

실행계획을 살펴보시면 어디 구간에서 시간이 많이 걸리는지 체크해 볼 수 있습니다.


by DarkBee [2019.08.07 11:41:57]

드라이빙 b 테이블 기준으로 

 

SELECT straight_join 
               count(*)
  FROM tn_mer_pan b 
     INNER JOIN tn_mer a 
         ON b.mer_sn=a.mer_sn 
 WHERE 1=1 
       AND a.member ='N' 
       AND ifnull(a.email_yn, 'Y') = 'Y' 
       AND b.pan_secsn = 'N' 
       AND b.birth < ((YEAR(NOW())-14)+1) 
       AND NOT EXISTS 
       (SELECT * 
         FROM tn_only_result s1 
        WHERE a.mer_sn = s1.mer_sn 
              AND s1.only_sn = 180 
       ) ;

 

 


by 박준수 [2019.08.08 12:29:09]

답변감사합니다!

하지만 이 방법으로는 1시간째 결과가 안나오네요


by 꼬랑지 [2019.08.07 13:56:21]

테이블 a,b를 조인을 한 후 not exists문으로 필터링을 하고 있는데요 그렇다면 필터링되어 추출할 필요가 없는 데이타까지 조인된다는 의미죠.

조인전에 필터링해서 불필요한 데이타를 제거한 후 a,b를 조인해 보면 어떨까요?

그리고 tn_only_result 테이블에서 * 로 하지말고 pk구성칼럼인 mer_sn 만 select절에 놓으면 인덱스만 스캔해서 속도가 더 빨라질 수도 있습니다.


by 박준수 [2019.08.08 12:29:33]

답변감사합니다

조언대로 해보겠습니다!


by 마농 [2019.08.09 08:16:02]
SELECT COUNT(*)
  FROM tn_mer a
 INNER JOIN tn_mer_pan b
    ON a.mer_sn = b.mer_sn
  LEFT OUTER JOIN tn_only_result s1
    ON a.mer_sn = s1.mer_sn
   AND s1.only_sn = 180
 WHERE 1=1
   AND a.member ='N' 
   AND IFNULL(a.email_yn, 'Y') = 'Y' 
   AND b.pan_secsn = 'N' 
   AND b.birth < ((YEAR(NOW())-14)+1)
   AND s1.mer_sn IS NULL
;

 


by 박준수 [2019.08.22 01:08:28]

외근으로 오랜시간 밖에만 있어서 너무 늦게 확인했습니다

답변 진심으로 감사드립니다

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입