똥글이꺼
368
2019-05-16 10:15:08
4
100

Mysql NOT In 개선방법좀 알려주세요.


NUM 값은 대체로 

00100100010001

00100500010001

00100400010001

00100300010001

NUM의 앞자리  ('001001','001005','001006','001008') 설정한 값을 제외하고

셀렉트 하고 싶은데, 

NOT IN 을 쓰면 성능이 안좋다고하여. 다른방법이 있을까요 ?


SELECT * FROM TABLE
WHERE SUBSTRING(NUM,1,6) NOT IN ('001001','001005','001006','001008')



0
0
  • 답변 4

  • 유리세계
    1k
    2019-05-16 10:18:21

    음... 정규식이요?

    mysql 은 where절에 정규식 되는걸로 아는데

    1
  • curioustore
    1k
    2019-05-16 10:20:07

    고정값 4개만 거르고 보는거면 개선할 필요 없을 것 같은데요.

    1
  • zepinos
    18k
    2019-05-16 10:20:27 작성 2019-05-16 10:26:26 수정됨

    select * from table

    where num not like '001001%'

        and num not like '001005%'

        and num not like '001006%'

        and num not like '001008%'


    not in 이 나쁜 것보다 num 컬럼을 함수로 변환한 뒤 in 으로 검색하기 때문에 num 에 인덱스가 있어도 index 를 이용할 수 없습니다. 반대로 like 을 이용한 전방일치(앞내용이 일치하는 것)일 경우에는 인덱스를 이용하기 때문에 성능상 차이가 납니다.

    2
  • 르매
    382
    2019-05-16 10:27:25

    num에 인덱스가 있겠죠?

    num에 걸린 인덱스를 사용하려면, LIKE와 LEFT OUTER JOIN을 이용한 차집합 쿼리를 사용해 볼 수 있습니다.


    DROP TABLE IF EXISTS t;
    
    CREATE TABLE t (`num` char(14) NOT NULL PRIMARY KEY) ENGINE = InnoDB;
    
    INSERT t VALUES ('00100100010001')
        , ('00100500010001')
        , ('00100400010001')
        , ('00100300010001');
    
    SELECT STRAIGHT_JOIN t.*
    FROM t FORCE INDEX FOR JOIN (PRIMARY)
        LEFT OUTER JOIN (
            SELECT '001001%' AS num UNION ALL
            SELECT '001005%' UNION ALL
            SELECT '001006%' UNION ALL
            SELECT '001008%'
        ) s ON t.num LIKE s.num
    WHERE s.num IS NULL;


    1
  • 로그인을 하시면 답변을 등록할 수 있습니다.