[SQL Tuning] 테이블 스캔, 인덱스 스캔의 개념과 예시

아리엘 (Ariel)·2024년 5월 7일
1

SQL

목록 보기
12/14
post-thumbnail

1. 테이블 풀 스캔 (table full scan)

인덱스를 사용하지 않고 디스크에 위치한 테이블 데이터에 바로 가서 처음부터 끝까지 데이터를 스캔하는 방식

  • 적용 상황

    • WHERE 절의 조건문을 기준으로, 활용할 수 있는 인덱스가 없는 경우
    • 전체 데이터를 대비해서 대량의 데이터가 필요할 경우
  • 전체 데이터를 검색하므로 성능⬇️

SELECT * 
FROM students;


2. 인덱스 범위 스캔 (index range scan)

인덱스를 범위 기준으로 스캔한 후, 스캔 결과를 토대로 테이블 데이터를 찾는 방식

  • 비교 및 연산 구문 (BETWEEN~AND, <, >, LIKE 등)을 사용한 경우 인덱스 범위 스캔을 수행한다.
  • 효율성 관점
    • 좁은 범위를 스캔할 때, 효율성 ⬆️
    • 넓은 범위를 스캔할 때, 효율성 ⬇️
SELECT * 
FROM students 
WHERE age BETWEEN 10 AND 15;


3. 인덱스 풀 스캔 (index full scan)

인덱스를 처음부터 끝까지 스캔하는 방식 (테이블에 접근하지 않는다.)

  • 인덱스 크기 < 테이블 크기 ➡️ 인덱스 풀 스캔 성능 > 테이블 풀 스캔 성능
  • 그럼에도, 인덱스 "풀" 스캔이므로 검색 범위를 최소화하는 방향으로 SQL 튜닝이 필요하다.


4. 인덱스 고유 스캔 (index unique scan)

기본 키 OR 고유 인덱스로 테이블에 접근하는 방식

  • 인덱스를 사용하는 스캔 방식 중 가장 효율적이다.
  • WHERE절에 = 조건으로 작성한다.
SELECT * 
FROM students 
WHERE student_id = 101;
  • 조인 열이 기본 키 OR 고유 인덱스의 선두 열*로 설정되었을 때 활용한다.
SELECT s.student_id, s.name, r.course_id
FROM students s
JOIN registrations r ON s.student_id = r.student_id;

student_idstudents 테이블의 기본 키이자 선두 열이다. 조인 조건에서 이 열을 사용함으로써 인덱스 고유 스캔을 활용하여 빠르게 관련 데이터를 찾을 수 있다.

*선두 열: 인덱스가 여러 열로 구성된 경우, 쿼리에서 인덱스의 첫 번째 열(선두 열)을 사용하면 인덱스 검색 효율이 극대화된다. 선두 열을 기준으로 인덱스가 가장 먼저 정렬되기 때문이다.


5. 인덱스 루스 스캔 (index loose scan)

인덱스의 필요한 부분들만 골라 스캔하는 방식

  • WHERE 절 조건문을 기준으로 필요한 데이터를 구분한 뒤, 불필요한 데이터의 인덱스 키는 무시한다.
  • GROUP BY, MAX(), MIN() 가 사용되었을 때 작동한다. 예를 들어, 오름차순으로 정렬된 인덱스에서 최댓값이나 최솟값이 필요한 경우
SELECT MIN(phone_number) 
FROM emergency_contacts 
WHERE student_id = 101 
GROUP BY student_id;


6. 인덱스 병합 스캔 (index merge scan)

테이블 내에 생성된 인덱스들을 통합해서 스캔하는 방식

  • WHERE 문 조건절의 열들이 서로 다른 인덱스로 존재하면, 옵티마이저가 해당하는 인덱스를 가져와서 모두 활용하는 방식을 취한다.
  • 개별 인덱스를 각각 수행하므로 인덱스 접근 시간이 몇 배가 걸린다.
  • 따라서, 별개로 생성된 인덱스들은 하나의 인덱스로 통합하여 SQL 튜닝을 수행하거나
  • SQL문을 독립된 하나의 인덱스만 수행하도록 변경할 수 있다.

1) 인덱스 통합 방법 : 결합 (union)

SELECT name, age, grade
FROM students
WHERE age >= 10 OR grade = '5th';

각 인덱스를 개별적으로 스캔한 후, 각 스캔 결과를 합쳐 최종 결과를 생성한다.

2) 인덱스 통합 방법 : 교차 (intersection)

SELECT name, age, grade
FROM students
WHERE age >= 10 AND grade = '5th';

age 열과 grade 열에 각각 적용된 인덱스를 활용하여, 두 조건을 동시에 만족하는 데이터를 더 효율적으로 찾을 수 있다.


📌 Source

  • 양바른, 「업무에 바로 쓰는 SQL 튜닝」, 한빛미디어, 2021


💡 질문과 피드백은 댓글에 남겨주시기 바랍니다.
❤️ 도움이 되셨다면 공감 부탁드립니다.


profile
Data Analyst / Engineer

0개의 댓글