Skip to content

MySQL ‐ Why don't use prefix index in default

woojin.jang edited this page Jul 19, 2026 · 1 revision

접두사 인덱스란(Prefix Index)

  • 보통 인덱스는 컬럼 값 "전체"를 대상으로 만든다.
  • 접두사 인덱스는 문자열 컬럼의 앞에서부터 지정한 길이만큼만 잘라서 인덱스를 만든다.
-- email 컬럼 전체가 아니라, 앞 10글자만으로 인덱스 생성
CREATE INDEX idx_email ON member (email(10));

왜 이런 게 있는가(존재 이유)

  • 인덱스도 디스크와 메모리를 차지하는 별도의 자료구조라는 점을 명심해야 한다.
    • 인덱스가 클수록, 저장 공간을 많이 차지한다.
    • 인덱스가 클수록, 메모리(버퍼 풀)에 적게 올라가서 캐시 효율이 떨어진다.
    • 인덱스가 클수록, 인덱스 갱신(INSERT/UPDATE) 비용도 커진다.
  • VARCHAR(1000) 이나 URL, 긴 설명글처럼 값이 아주 긴 컬럼은 전체를 인덱싱하면 인덱스가 비대해진다.
  • 이럴 때 "어차피 앞부분만 봐도 대부분 구분되니까" 앞 N글자만 인덱싱해서 크기를 확 줄이는 것이 접두사 인덱스다.
  • 참고 : TEXT, BLOB 타입은 전체 인덱싱이 불가능해서, 인덱스를 걸려면 반드시 접두사 인덱스를 써야 한다.

그런데 왜 기본으로 쓰지 않는가(핵심)

  • 접두사 인덱스는 크기를 아끼는 대신 아래 기능들을 포기한다. 그래서 "기본"이 아니라 "필요할 때만"이다.

1. 선택도(Selectivity)가 떨어질 수 있다

  • 앞 N글자가 짧으면 서로 다른 값인데도 접두사가 같아지는 경우가 많아진다.
  • 예시 : 이메일을 email(3)으로 인덱싱했는데 abc...로 시작하는 회원이 수천 명이면, 인덱스를 타도 결국 수천 건을 다시 걸러내야 한다 → 인덱스 효과가 약해진다.

2. 커버링 인덱스로 쓸 수 없다

  • 인덱스에는 값의 앞부분만 있으므로, 인덱스만 읽어서 원래 컬럼 값을 되돌려줄 수 없다.
  • 따라서 항상 실제 테이블 행을 다시 읽어야 한다.(Using index 최적화 불가)

3. 정렬(ORDER BY) / 그룹핑(GROUP BY)에 쓸 수 없다

  • 앞부분만으로는 전체 값의 순서를 알 수 없다.
  • 예시 : appleapplication은 앞 5글자가 appl...로 같아서, 접두사만으로는 둘의 정확한 정렬 순서를 판단하지 못한다.
  • 그래서 접두사 인덱스는 ORDER BY나 GROUP BY의 정렬을 대신해 줄 수 없다.

접두사 길이는 어떻게 정하나?

  • 너무 짧으면 → 선택도가 낮아 인덱스 효과가 없다.
  • 너무 길면 → 공간 절약이라는 목적 자체가 사라진다.
  • 그래서 "전체 컬럼의 선택도"에 최대한 근접하면서도 가장 짧은 길이를 찾는다.
-- 1) 전체 컬럼의 선택도 (기준값)
SELECT COUNT(DISTINCT email) / COUNT(*) AS full_selectivity
FROM member;

-- 2) 여러 접두사 길이의 선택도를 비교
SELECT
  COUNT(DISTINCT LEFT(email, 5)) / COUNT(*) AS sel_5,
  COUNT(DISTINCT LEFT(email, 8)) / COUNT(*) AS sel_8,
  COUNT(DISTINCT LEFT(email, 12)) / COUNT(*) AS sel_12
FROM member;
  • sel_N 값이 full_selectivity에 충분히 가까워지는 지점의 길이를 고른다.

언제 쓰면 좋은가 / 언제 피해야 하는가

  • 쓰면 좋은 경우
    • 값이 매우 긴 문자열 컬럼인데, 앞부분만으로도 값이 충분히 구분되는 경우
    • TEXT / BLOB처럼 애초에 전체 인덱싱이 불가능한 컬럼
  • 피해야 하는 경우
    • 해당 컬럼으로 ORDER BY / GROUP BY를 자주 하는 경우
    • 커버링 인덱스로 조회 성능을 끌어올리고 싶은 경우
    • 앞부분이 거의 비슷해서 선택도가 낮은 값(예시 : https://www. 로 시작하는 URL, 공통 접두어가 긴 코드값)

📖 Code Philosophy

📖 Java

📖 Kotlin

📖 Coroutine

📖 Spring

📖 Spring Security

📖 Spring Batch

📖 Database

📖 MySQL

📖 Redis

📖 JPA

📖 QueryDsl

📖 MSA

📖 Kafka

📖 Apache Flink

  • [Apache Flink - Apache Flink Architecture]
  • [Apache Flink - Stream Processing]
  • [Apache Flink - Data Stream API & Window]
  • [Apache Flink - State Management]

📖 HTTP

📖 AWS

📖 Docker

📖 Kubernetes

📖 Github Actions

📖 Jenkins

📖 Nginx

📖 Monitoring

📖 Test(feat. Load Testing)

  • [Test - Load Testing Fundamentals]
  • [Test - Identifying Bottlenecks with Load Testing]
  • [Test - Resolving Bottlenecks and Improving Performance]

📖 Test(feat. Java)

📖 Spring AI

📖 gRPC

  • [gRPC - Writing .proto Files with Protocol Buffers]
  • [gRPC - Various Communication Patterns in gRPC]
  • [gRPC - gRPC Optimization Techniques and Advanced Features]

📖 TDD(Test-Driven-Development)

📖 PostgreSQL

  • [PostgreSQL - Docker만을 사용하는 경량화된 환경 구성 방법]
  • [PostgreSQL - PostgreSQL에서 제공하는 데이터 타입]
  • [PostgreSQL - PostgreSQI의 JSONB, 역인덱싱과 활용 방법]
  • [PostgreSQL - 데이터베이스 성능을 위한 최적화 패턴 및 전략]
  • [PostgreSQL - 트랜잭션과 ACID, Isolation 수준별 차이]
  • [PostgreSQL - Database Lock 교착상태와 읽기/쓰기 성능을 보장하는 MVCC 모델]
  • [PostgreSQL - pgvector와 벡터 저장, 유사도 검색 패턴 개념]
  • [PostgreSQL - 벡터 인덱스 최적화와 벡터 검색과 전문 검색 결합 패턴]
  • [PostgreSQL - PostgreSQL 플러그인]
  • [PostgreSQL - PostGIS - 공간 쿼리와 GIST 인덱스, 지리 타입과 공간 쿼리를 위한 타입과 기본 함수]
  • [PostgreSQL - pg_search - 검색 엔진 없이 텍스트 검색 구현과 주의사항]
  • [PostgreSQL - 단일 인스턴스 한계를 극복하는 분산 패턴과 스케줄링, 분산 환경 구축 방법]
  • [PostgreSQL - Citus - 분산 테이블과 분산 쿼리를 위한 Extension과 데이터 분산 처리]
  • [PostgreSQL - pg_cron - PostgreSQL로 구성하는 CronJob]
  • [PostgreSQL - 스케줄러 + 분산 처리를 동시에 도입하는 주기적 집계 쿼리 패턴]

📖 Workflow-Driven Techniques for Large-Scale Traffic Processing

  • [Workflow-Driven Techniques for Large-Scale Traffic Processing - Kafka + Debezium을 활용한 CDC 패턴 설계]
  • [Workflow-Driven Techniques for Large-Scale Traffic Processing - Temporal을 활용한 워크플로우 패턴]
  • [Workflow-Driven Techniques for Large-Scale Traffic Processing - Docker와 경량 이미지를 활용한 환경 구축 방법]
  • [Workflow-Driven Techniques for Large-Scale Traffic Processing - Kafka에서의 메시지 Delivery Guarantee]
  • [Workflow-Driven Techniques for Large-Scale Traffic Processing - 실시간 동기화의 핵심 CDC]
  • [Workflow-Driven Techniques for Large-Scale Traffic Processing - MySQL Binary Log 기반의 CDC]
  • [Workflow-Driven Techniques for Large-Scale Traffic Processing - Binary Log 기반의 CDC 구현 플랫폼 Debezium이란?]
  • [Workflow-Driven Techniques for Large-Scale Traffic Processing - Debezium Architecture]
  • [Workflow-Driven Techniques for Large-Scale Traffic Processing - Debezium Architecture Best Practice와 주의사항]

📖 Reactive Programming

📖 ElasticSearch

  • [ElasticSearch - Search Fundamentals & How Search Works]
  • [ElasticSearch - Korean-Optimized Search]
  • [ElasticSearch - Mapping & Data Types]
  • [ElasticSearch - Common Search Features]
  • [ElasticSearch - Building a Product Search Engine with Elasticsearch]
  • [ElasticSearch - Deploying Elasticsearch with Elastic Cloud]
  • [ElasticSearch - Managing Documents]
  • [ElasticSearch - Analysis & Mapping]
  • [ElasticSearch - Search Fundamentals]
  • [ElasticSearch - Query Joins]
  • [ElasticSearch - Processing Search Results]
  • [ElasticSearch - Aggregations]
  • [ElasticSearch - Tips for Improving Search Results]
  • [ElasticSearch - Elasticsearch Clients]
  • [ElasticSearch - Understanding How Elasticsearch Works]
  • [ElasticSearch - Monitoring Elasticsearch]
  • [ElasticSearch - Elasticsearch Troubleshooting]

Clone this wiki locally