인덱스는 특정 열 또는 테이블의 열 집합에 대한 데이터를 빠르게 검색하는 데 사용되는 특수 데이터 구조(주로 B-트리 기반)입니다. 인덱스는 검색, 정렬 및 필터링을 가속화하여 검색하는 행의 수를 줄입니다.
인덱스 유형:
인덱스는 다음을 가속화합니다:
느리게 만들 수 있는 경우:
인덱스 생성 예:
CREATE INDEX idx_user_email ON users (email);
인덱스가 도움이 되지 않는 예:
SELECT * FROM users WHERE lower(email) = 'test@example.com'; -- email에 인덱스가 생성되어 있지만, 쿼리에서 lower(email) 함수를 사용하므로 인덱스가 사용되지 않음!
모든 열에 인덱스를 추가하면 모든 SELECT 쿼리의 실행이 항상 빨라질까요?
답변:
아니요. 인덱스는 필터링이나 정렬이 인덱스된 열에서 함수나 인덱스 사용을 방해하는 연산 없이 엄격하게 발생할 때만 쿼리를 가속화합니다. 너무 많은 인덱스는 INSERT/UPDATE/DELETE를 느리게 할 뿐만 아니라 많은 공간을 차지하며, 일부 복잡한 쿼리는 인덱스를 완전히 무시할 수 있습니다 (예: 조건을 사용하여 범위를 스캔할 때).
예:
SELECT * FROM orders WHERE year(order_date) = 2023; -- order_date에만 인덱스가 있는 경우, year() 함수 때문에 인덱스가 작동하지 않음
역사
전자 메일 시스템에서는 자주 사용되는 각 필드에 대해 인덱스를 생성하는 트리거가 만들어졌습니다. 6개월 후 시스템 성능이 저하되었고, 행을 삽입하거나 변경하는 데 4-5배 더 많은 시간이 소요되었습니다. 감사 후 인덱스 수가 줄어들어 시스템이 가속화되었습니다.
역사
광고 플랫폼에서는
substring(url, 1, 10)필터가 포함된 SELECT 쿼리가 자주 발생했습니다. url에 대한 인덱스가 있음에도 불구하고 SQL은 substring 함수 때문에 인덱스를 사용하지 않았습니다. 해결책은 이러한 선택을 위한 별도의 필드를 도입하고 그에 대한 인덱스를 생성하는 것이었습니다.
역사
로열티 프로그램에서 (customer_id, shop_id) 필드에 대한 복합 인덱스가 생성되었습니다. shop_id만으로 쿼리할 경우 인덱스가 적용되지 않아 전체 테이블 스캔이 발생했습니다. 이는 보너스 계산 시 인덱스 이점을 잃게 만들었습니다. 최적화로 shop_id에 대한 별도의 인덱스가 추가되었습니다.