상세 컨텐츠

본문 제목

쿼리 수행할때 중복제거 distinct 넣고 안넣고 플랜에서 차이

IT/DB

by JR 2025. 12. 17. 16:56

본문

300x250
반응형

 

 

 

 

결론부터
👉 중복이 없는 컬럼이어도 DISTINCT를 쓰면 실행 계획은 달라질 수 있고, 보통은 “불리”해집니다.
👉 단, DB가 중복이 없다는 걸 플랜 단계에서 확신할 수 있으면 차이가 거의 없을 수도 있습니다.


1️⃣ DISTINCT가 들어가면 옵티마이저가 하는 일

SQL:

SELECT DISTINCT col
FROM table;

 

DB 입장에서는 반드시 이걸 보장해야 합니다.

  • 실제 데이터가 중복이 있든 없든
  • “중복 제거 연산”을 수행해야 함

그래서 내부적으로는 보통 아래 중 하나가 추가됩니다.

🔹 ① SORT + UNIQUE

→ SORT
  → TABLE ACCESS / INDEX SCAN

🔹 ② HASH AGGREGATE

→ HASH UNIQUE (또는 HASH AGG)
  → TABLE ACCESS / INDEX SCAN

 

📌 이 단계 자체가 비용(cost)을 만듭니다.


2️⃣ DISTINCT 없는 경우

SELECT col
FROM table;
  • 그냥 읽어서 바로 반환
  • 정렬 / 해시 / 메모리 연산 없음
  • 인덱스 있으면 INDEX RANGE SCAN → 바로 출력 가능

👉 플랜이 훨씬 단순해짐


3️⃣ “근데 실제로 중복이 없는 컬럼인데?”

여기서 중요한 포인트 👇

✅ DB가 “중복 없음”을 확신할 수 있는 경우

  • PRIMARY KEY
  • UNIQUE INDEX
  • UNIQUE CONSTRAINT

이런 경우:

SELECT DISTINCT pk_col FROM table;

 

👉 옵티마이저가 판단:

“어차피 중복 없음 → DISTINCT 의미 없음”

 

📌 이러면 실제 실행 계획에서

  • SORT UNIQUE 단계가 사라지거나
  • 그냥 무시되는 경우도 많음

⚠️ 단, DB 종류/버전에 따라 다름 (Oracle, MySQL, PostgreSQL 다름)


❌ DB가 “중복 없음”을 알 수 없는 경우

  • 논리적으로는 중복 없지만
  • 제약조건 / 유니크 인덱스 없음

이때는:

  • 무조건 중복 제거 단계 수행
  • 실제로 중복이 없더라도
    • SORT
    • HASH
    • TEMP 사용 가능

👉 데이터 많을수록 체감 성능 차이 큼


4️⃣ 실제 플랜 차이 예시 (개념)

DISTINCT 없음

INDEX RANGE SCAN idx_col
→ RETURN ROWS

DISTINCT 있음

INDEX RANGE SCAN idx_col
→ SORT UNIQUE
→ RETURN ROWS

 

📌 SORT UNIQUE 하나 들어가는 순간:

  • CPU 사용 증가
  • 메모리 부족 시 TEMP I/O 발생
  • 병렬 쿼리 시 비용 더 커짐

5️⃣ JOIN / GROUP BY랑 같이 쓰일 때는 더 치명적

SELECT DISTINCT a.col
FROM a
JOIN b ON ...
  • JOIN 결과가 커진 뒤
  • 마지막에 DISTINCT 수행

👉 이건 진짜 성능 차이 큼
(“이미 늦었다” 상태에서 중복 제거)


6️⃣ 그래서 실무 결론은?

✅ 중복이 없다는 게 확실하면

  • DISTINCT 쓰지 마세요
  • 대신 DB가 알 수 있게:
    • UNIQUE INDEX
    • PK
    • CONSTRAINT 추가

✅ DISTINCT 써야 한다면

  • 컬럼 수 최소화
  • JOIN 결과 커지기 전에 중복 줄이기
  • 가능하면 GROUP BY로 의도를 명확히

7️⃣ 한 줄 요약 (면접/실무용)

“실제 중복이 없어도 DISTINCT는 중복 제거 연산을 유발할 수 있고,
DB가 유니크함을 보장하지 못하면 실행 계획과 성능 차이가 크게 난다.”


 

 

 

 

 

 

300x250
반응형

관련글 더보기