[TIL] Real MySQL

2025.03.18
·
3 min read

OR 연산과 인덱싱되지 않은 컬럼

WHERE account_type = '7' OR joined_at > '2022-07-24'
  • 같은 조건에서

  • account_type 에만 인덱스가 잡혀있으면

    • 풀스캔이 발생함

    • 어차피 joined_at 컬럼 조건을 탐색할때 풀스캔을 수행해야하기 때문임.

풀 스캔이 더 효율적인 경우

  • 데이터 분포도 에 따라 MySQL 옵티마이저가 인덱스 대신 풀 스캔을 수행할 수 있음.

    MySQL 옵티마이저의 판단 기준

    • 선택도(Selectivity)

      • 조건에 해당하는 데이터 비율이 어느정도인지

      • 선택도가 낮을수록

      인덱스가 유리하다

    • 데이터 분포

      • 테이블에 값에 고르게 분포되어 있는지

      • 특정 값이 대부분이 인지에 따라

    • 테이블 크기

      • 테이블이 작은 경우 풀 스캔이 인덱스보다 빠르다

    • 쿼리 조건

      • WHERE , JOIN , IN 같은 조건의 복잡성과 범위성

    테이블의 구성

    • 컬럼: group_name 에 인덱스가 존재함

      • a

      • b

      • c

      • d

      4가지 값이 존재한다

    • 데이터

      • 10,000 행이 있다고 가정함,

      • 분포는 다음과 같다

        • a

          • 4000행

        • b

          • 3000행

        • c

          • 2000행

        • d

          • 1000행

      • 쿼리1

        select *
        from sample_table
        where group_name in ('a', 'b');
        
        • a, b 의 비율이.. 전체 데이터의 70% 반환을 해야함

        • 인덱스 사용시 a b 를 각각 찾아야하는데, 결과적으로 70% 라는 큰 비율이기에 인덱스 탐색한 후 데이터 블록을 읽는 비용이 높아질 수 있음

          • 실제로 돌렸을때는 ,, 인덱스를 탔지만

          • 풀스캔으로 돌릴 가능성도 높다고 함.

      • 쿼리2

        select *
        from sample_table
        where group_name in ('c', 'd');
        
        • 반환 데이터 비율이 30% 상대적으로 데이터 선택도가 높다.

        • 인덱스를 옵티마이저가 사용할 가능성이 높음

        일단 뭐든 무조건 인덱스를 타고 풀스캔을 하는 건 아님.

        통계에 따라 다름.







- 컬렉션 아티클