λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
CS/Database

업무에 λ°”λ‘œ μ“°λŠ” SQL νŠœλ‹ 2 - SQL νŠœλ‹ μ‹€μŠ΅ (1)

by 주발2 2024. 10. 8.
λ°˜μ‘ν˜•

μ§€λ‚œ ν¬μŠ€νŒ…μ—μ„œ SQL νŠœλ‹ 이둠에 λŒ€ν•΄ μ‚΄νŽ΄λ³΄μ•˜λŠ”λ°μš”, 이번 ν¬μŠ€νŒ…μ—μ„œλŠ” μ‹€μ œ μ—¬λŸ¬ ν…Œμ΄λΈ”μ˜ 데이터λ₯Ό 기반으둜 쿼리의 λ¬Έμ œμ μ„ νŒŒμ•…ν•˜κ³ , νŠœλ‹ν•˜μ—¬ κ°œμ„ ν•΄ λ³΄κ² μŠ΅λ‹ˆλ‹€.

(μ‹€μ œ νŠœλ‹ μ „ SQL 문을 ν™•μΈν•˜μ—¬ 무엇이 λ¬Έμ œμΈμ§€ νŒŒμ•…ν•΄λ³΄κ³ , 직접 κ°œμ„ ν•΄λ³΄κ³  νŠœλ‹ ν›„ SQL 문을 ν™•μΈν•˜λŠ” 방식도 쒋을 것 κ°™μŠ΅λ‹ˆλ‹€.)

 

μ•…μ„± SQL νŠœλ‹μœΌλ‘œ 초보자 νƒˆμΆœν•˜κΈ°

싀무적인 SQL νŠœλ‹ 절차 μ΄ν•΄ν•˜κΈ°

1. SQL λ¬Έ μ‹€ν–‰ κ²°κ³Ό & ν˜„ν™© νŒŒμ•…

  • κ²°κ³Ό 및 μ†Œμš”μ‹œκ°„ 확인
  • 쑰인 / μ„œλΈŒμΏΌλ¦¬ ꡬ쑰
  • 동등 / λ²”μœ„ 쑰건

2. κ°€μ‹œμ 

  • ν…Œμ΄λΈ”μ˜ 데이터 건수
  • SELECT 절 컬럼 뢄석
  • 쑰건절 컬럼 뢄석
  • 그루핑 / μ •λ ¬ 컬럼

3. λΉ„κ°€μ‹œμ 

  • μ‹€ν–‰κ³„νš
  • 인덱슀 ν˜„ν™©
  • 데이터 λ³€κ²½ 좔이
  • 업무적 νŠΉμ§•

4. νŠœλ‹ λ°©ν–₯ νŒλ‹¨ & κ°œμ„  / 적용 (ν…ŒμŠ€νŠΈ)

 

SQL λ¬Έ λ‹¨μˆœ μˆ˜μ •μœΌλ‘œ μ°©ν•œ 쿼리 λ§Œλ“€κΈ°

μœ„ 데이터 μ„ΈνŒ…μ€ μ•„λž˜ λ ˆν¬μ§€ν† λ¦¬μ˜ sql νŒŒμΌμ„ 톡해 μ„€μ •ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

https://github.com/7ieon/SQLtune

 

GitHub - 7ieon/SQLtune

Contribute to 7ieon/SQLtune development by creating an account on GitHub.

github.com

 

ν…Œμ΄λΈ” 데이터 건수

No ν…Œμ΄λΈ” λͺ… 데이터 건수
1 κΈ‰μ—¬ 2,844,047
2 λΆ€μ„œ 9
3 λΆ€μ„œκ΄€λ¦¬μž 24
4 λΆ€μ„œμ‚¬μ›_맀핑 331,603
5 사원 300,024
6 μ‚¬μ›μΆœμž…κΈ°λ‘ 660,000
7 직급 443,308

 

 

ν…Œμ΄λΈ” 인덱슀 λͺ©λ‘

ν…Œμ΄λΈ”λͺ… ν‚€ μœ ν˜• ν‚€λͺ… ν‚€_ꡬ성열
κΈ‰μ—¬ PK PRIMARY KEY μ‚¬μ›λ²ˆν˜Έ + μ‹œμž‘μΌμž
INDEX I_μ‚¬μš©μ—¬λΆ€ μ‚¬μš©μ—¬λΆ€
λΆ€μ„œ PK PRIMARY KEY λΆ€μ„œλ²ˆν˜Έ
UNIQUE INDEX UI_λΆ€μ„œλͺ… λΆ€μ„œλͺ…
λΆ€μ„œκ΄€λ¦¬μž PK PRIMARY KEY μ‚¬μ›λ²ˆν˜Έ + λΆ€μ„œλ²ˆν˜Έ
INDEX I_λΆ€μ„œλ²ˆν˜Έ λΆ€μ„œλ²ˆν˜Έ
λΆ€μ„œμ‚¬μ›_맀핑 PK PRIMARY KEY μ‚¬μ›λ²ˆν˜Έ + λΆ€μ„œλ²ˆν˜Έ
INDEX I_λΆ€μ„œλ²ˆν˜Έ λΆ€μ„œλ²ˆν˜Έ
사원 PK PRIMARY KEY μ‚¬μ›λ²ˆν˜Έ
INDEX I_μž…μ‚¬μΌμž μž…μ‚¬μΌμž
INDEX I_성별_μ„± 성별 + μ„±
μ‚¬μ›μΆœμž…κΈ°λ‘ PK PRIMARY KEY 순번 + μ‚¬μ›λ²ˆν˜Έ
INDEX I_μΆœμž…λ¬Έ μΆœμž…λ¬Έ
INDEX I_지역 지역
INDEX I_μ‹œκ°„ μž…μΆœμž…μ‹œκ°„
직급 PK PRIMARY KEY μ‚¬μ›λ²ˆν˜Έ + 직급λͺ… + μ‹œμž‘μΌμž

 

1. κΈ°λ³Έ ν‚€λ₯Ό λ³€ν˜•ν•˜λŠ” λ‚˜μœ SQL λ¬Έ

νŠœλ‹ μ „ SQL, μ‹€ν–‰ κ³„νš

SELECT * 
FROM 사원 
WHERE SUBSTRING(μ‚¬μ›λ²ˆν˜Έ, 1, 4) = 1100
	AND LENGTH(μ‚¬μ›λ²ˆν˜Έ) = 5;

  • type = ALL μ΄λ―€λ‘œ ν’€ μŠ€μΊ” λ°©μ‹μœΌλ‘œ 인덱슀λ₯Ό μ‚¬μš©ν•˜μ§€ μ•Šκ³  ν…Œμ΄λΈ”μ— λ°”λ‘œ μ ‘κ·Ό ν•©λ‹ˆλ‹€.
  • 사원 ν…Œμ΄λΈ”μ˜ 전체 데이터가 μ•½ 30만건 μ΄λ―€λ‘œ, 거의 λͺ¨λ“  데이터에 μ ‘κ·Όν•©λ‹ˆλ‹€.

νŠœλ‹ ν›„ SQL, μ‹€ν–‰ κ³„νš

SELECT *
FROM 사원 
WHERE μ‚¬μ›λ²ˆν˜Έ BETWEEN 11000 AND 11009

  • κΈ°λ³Έ ν‚€ (μ‚¬μ›λ²ˆν˜Έ)λ₯Ό 가곡 없이 λ²”μœ„ 검색을 ν™œμš©ν•˜μ—¬ κΈ°λ³Έ ν‚€, 인덱슀λ₯Ό ν™œμš©ν•©λ‹ˆλ‹€.

 

2. μ‚¬μš©ν•˜μ§€ μ•ŠλŠ” ν•¨μˆ˜λ₯Ό ν¬ν•¨ν•˜λŠ” λ‚˜μœ SQL λ¬Έ

νŠœλ‹ μ „ SQL, μ‹€ν–‰ κ³„νš

SELECT IFNULL(성별, 'NO DATA') AS 성별, COUNT(1) 건수
FROM 사원
GROUP BY IFNULL(성별, 'NO DATA');

  • Extra ν•­λͺ©μ΄ Using temporary μ΄λ―€λ‘œ μž„μ‹œ ν…Œμ΄λΈ”μ„ μƒμ„±ν•©λ‹ˆλ‹€.

νŠœλ‹ ν›„ SQL, μ‹€ν–‰ κ³„νš

SELECT 성별, COUNT(1) 건수
FROM 사원
GROUP BY 성별;

  • Extra ν•­λͺ©μ— μž„μ‹œ ν…Œμ΄λΈ”(Using temporary) 없이 인덱슀만 μ‚¬μš©ν•˜μ—¬ 데이터λ₯Ό μΆ”μΆœν•©λ‹ˆλ‹€.
  • 단, 성별 μ»¬λŸΌμ—λŠ” NOT NULL이고, NULL 데이터가 μ—†λ‹€λŠ” κ°€μ • ν•˜μ— νŠœλ‹ν•œ μΏΌλ¦¬μž…λ‹ˆλ‹€.

 

3. ν˜•λ³€ν™˜μœΌλ‘œ 인덱슀λ₯Ό ν™œμš©ν•˜μ§€ λͺ»ν•˜λŠ” λ‚˜μœ SQL λ¬Έ

νŠœλ‹ μ „ SQL, μ‹€ν–‰ κ³„νš

SELECT COUNT(1) FROM κΈ‰μ—¬ WHERE μ‚¬μš©μ—¬λΆ€ = 1;

  • filtered ν•­λͺ©μ΄ 10μ΄λ―€λ‘œ, MySQL μ—”μ§„μœΌλ‘œ κ°€μ Έμ˜¨ 데이터 쀑 10%λ₯Ό μΆ”μΆœν•΄μ„œ μ΅œμ’… 데이터λ₯Ό 좜λ ₯함을 μ•Œ 수 μžˆμŠ΅λ‹ˆλ‹€.
  • rows에 ν•΄λ‹Ήν•˜λŠ” 2,838,398건의 데이터 쀑 10%에 ν•΄λ‹Ήν•˜λŠ” μ•½ 3만 건의 데이터가 μ΅œμ’… 좜λ ₯되리라고 μ˜ˆμΈ‘ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  • λŒ€λž΅ 0.3초

νŠœλ‹ ν›„ SQL, μ‹€ν–‰ κ³„νš

SELECT COUNT(1) FROM κΈ‰μ—¬ WHERE μ‚¬μš©μ—¬λΆ€ = '1';

  • μ‚¬μš©μ—¬λΆ€ 열은 λ¬Έμžν˜• char(1) 데이터 μœ ν˜•μœΌλ‘œ κ΅¬μ„±λ˜μ–΄μ„œ, 이전 μΏΌλ¦¬μ—μ„œλŠ” 숫자 μœ ν˜•μœΌλ‘œ μ¨μ„œ 데이터에 μ ‘κ·Όν–ˆμœΌλ―€λ‘œ DBMS λ‚΄λΆ€μ˜ λ¬΅μ‹œμ  ν˜•λ³€ν™˜μ΄ λ°œμƒν–ˆκ³ , κ·Έ κ²°κ³Ό 인덱슀λ₯Ό μ œλŒ€λ‘œ ν™œμš©ν•˜μ§€ λͺ»ν•˜κ³  전체 데이터λ₯Ό μŠ€μΊ”ν•˜μ˜€μŠ΅λ‹ˆλ‹€.
  • λŒ€λž΅ 0.02초
였라클의 경우, νŠΉμ • 버전 이상(?) μ—μ„œλŠ” μœ„μ™€ 같은 λ¬Έμ œκ°€ λ°œμƒν•˜μ§€ μ•Šκ²Œ μžλ™μœΌλ‘œ ν˜•λ³€ν™˜μ„ μ²˜λ¦¬ν•΄μ£ΌλŠ” κΈ°λŠ₯이 μžˆμ–΄μ„œ μœ„μ™€ 같은 λ¬Έμ œκ°€ λ°œμƒν•˜μ§€ μ•Šμ•˜λ˜ κ²ƒμœΌλ‘œ 기얡을 ν•˜λŠ”λ°, ν™•μ‹€ν•˜μ§€λŠ” μ•ŠμŠ΅λ‹ˆλ‹€.

 

4. λ‹€μˆ˜ 쿼리λ₯Ό UNION μ—°μ‚°μžλ‘œλ§Œ ν•©μΉ˜λŠ” λ‚˜μœ SQL λ¬Έ

νŠœλ‹ μ „ SQL, μ‹€ν–‰ κ³„νš

SELECT 'M' AS 성별, μ‚¬μ›λ²ˆν˜Έ
FROM 사원
WHERE 성별 = 'M'
  AND μ„± = 'Baba'

UNION

SELECT 'F' AS 성별, μ‚¬μ›λ²ˆν˜Έ
FROM 사원
WHERE 성별 = 'F'
  AND μ„± = 'Baba';

  • idκ°€ 1, 2인 행은 사원 ν…Œμ΄λΈ”μ— λŒ€ν•΄ I_성별_μ„± 인덱슀λ₯Ό ν™œμš©ν•©λ‹ˆλ‹€.
  • idκ°€ 3인 행은 idκ°€ 1, 2인 ν–‰μ˜ κ²°κ³Όλ₯Ό ν†΅ν•©ν•˜μ—¬ 쀑볡을 μ œκ±°ν•˜λŠ” μž‘μ—…μ„ ν•©λ‹ˆλ‹€. μ—¬κΈ°μ„œ μž„μ‹œ ν…Œμ΄λΈ”(Using temporary)을 μƒμ„±ν•˜κ³  κ·Έ λ‚΄λΆ€μ—μ„œ 각 결과의 UNION μ—°μ‚° μž‘μ—…μ„ μˆ˜ν–‰ν•˜λ¦¬λΌ μ˜ˆμΈ‘ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

 

νŠœλ‹ ν›„ SQL, μ‹€ν–‰ κ³„νš

SELECT 'M' AS 성별, μ‚¬μ›λ²ˆν˜Έ
FROM 사원
WHERE 성별 = 'M'
  AND μ„± = 'Baba'

UNION ALL

SELECT 'F' AS 성별, μ‚¬μ›λ²ˆν˜Έ
FROM 사원
WHERE 성별 = 'F'
  AND μ„± = 'Baba';

  • λ‹¨μˆœνžˆ UNION -> UNION ALL 으둜 λ³€κ²½ν•©λ‹ˆλ‹€.
  • 첫 번째 SELECT와 두 번째 SELECT의 κ²°κ³Ό 데이터가 μ€‘λ³΅λ˜μ§€ μ•ŠμœΌλ―€λ‘œ, 쀑볡 μ œκ±°ν•˜λŠ” μž‘μ—…μ΄ ν•„μš”ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
  • νŠœλ‹ μ „ μ‹€ν–‰ κ³„νšκ³ΌλŠ” 달리 μ„Έ 번째 μΆ”κ°€ ν–‰(Using temporary)은 ν•„μš”ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

 

5. 인덱슀 κ³ λ € 없이 열을 μ‚¬μš©ν•˜λŠ” λ‚˜μœ SQL λ¬Έ

νŠœλ‹ μ „ SQL, μ‹€ν–‰ κ³„νš

SELECT μ„±, 성별, COUNT(*) AS 카운트
FROM 사원
GROUP BY μ„±, 성별;

  • I_성별_μ„± 인덱슀λ₯Ό ν™œμš©ν•˜κ³ , μž„μ‹œ ν…Œμ΄λΈ” (Using temporary)을 μƒμ„±ν•˜μ—¬ μ„±κ³Ό 성별을 그루핑해 카운트 연산을 μˆ˜ν–‰ν•©λ‹ˆλ‹€.

I_성별_μ„± μΈλ±μŠ€λŠ” 성별과 μ„± 순으둜 μƒμ„±λœ 인덱슀둜, 성별 κΈ°μ€€μœΌλ‘œ μ •λ ¬λœ λ’€ μ„± κΈ°μ€€μœΌλ‘œ μ •λ ¬λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

 

νŠœλ‹ ν›„ SQL, μ‹€ν–‰ κ³„νš

SELECT μ„±, 성별, COUNT(*) AS 카운트
FROM 사원
GROUP BY 성별, μ„±;

  • νŠœλ‹ ν›„ μ‹€ν–‰ κ³„νšμ—μ„œλŠ” λ³„λ„λ‘œ μž„μ‹œ ν…Œμ΄λΈ”μ„ μƒμ„±ν•˜μ§€ μ•Šκ³ λ„ μž‘μ—…μ„ μˆ˜ν–‰ν•©λ‹ˆλ‹€. (인덱슀 ν™œμš©, 성별 -> μ„±)
  • νŠœλ‹ μ „ μ†Œμš” μ‹œκ°„(0.3초) -> νŠœλ‹ ν›„ μ†Œμš” μ‹œκ°„(0.03초)

 

6. 동등 쑰건으둜 인덱슀λ₯Ό μ‚¬μš©ν•˜λŠ” λ‚˜μœ SQL λ¬Έ

νŠœλ‹ μ „ SQL, μ‹€ν–‰ κ³„νš

SELECT * FROM μ‚¬μ›μΆœμž…κΈ°λ‘ WHERE μΆœμž…λ¬Έ = 'B';

  • μΆœμž…λ¬Έ B에 λŒ€ν•œ λͺ…ν™•ν•œ μƒμˆ˜ 쑰건으둜 ref ν•­λͺ©μ΄ const둜 좜λ ₯λ©λ‹ˆλ‹€.
  • ν•˜μ§€λ§Œ μ‚¬μ›μΆœμž…κΈ°λ‘ ν…Œμ΄λΈ”μ˜ 전체 데이터(660,000) 쀑 μΆœμž…λ¬Έμ΄ B에 ν•΄λ‹Ήν•˜λŠ” λ°μ΄ν„°λŠ” μ•½ 50% (300,000)에 ν•΄λ‹Ήν•˜λ―€λ‘œ, 이λ₯Ό μœ„ν•΄ 인덱슀λ₯Ό ν™œμš©ν•˜λŠ” 게 κ³Όμ—° νš¨μœ¨μ μΌμ§€ 고민해봐야 ν•©λ‹ˆλ‹€. (인덱슀 손읡뢄기점)

μΉœμ ˆν•œ SQL νŠœλ‹

 

νŠœλ‹ ν›„ SQL, μ‹€ν–‰ κ³„νš

SELECT * FROM μ‚¬μ›μΆœμž…κΈ°λ‘ IGNORE INDEX(I_μΆœμž…λ¬Έ) WHERE μΆœμž…λ¬Έ = 'B';

  • νŠœλ‹ ν›„ μ‹€ν–‰ κ³„νšμ€ ν…Œμ΄λΈ” ν’€ μŠ€μΊ”(type: ALL)으둜 μˆ˜ν–‰λ¨μ„ 확인할 수 μžˆμŠ΅λ‹ˆλ‹€.
  • 즉, 인덱슀λ₯Ό μ‚¬μš©ν•˜μ§€ μ•Šμ€ 채 μ•½ 66만건의 전체 데이터λ₯Ό 가져와 μ‘°κ±΄μ ˆμ— ν•„μš”ν•œ 데이터λ₯Ό μΆ”μΆœν•˜λŠ” λ°©μ‹μœΌλ‘œ, 랜덀 μ•‘μ„ΈμŠ€κ°€ λ°œμƒν•˜μ§€ μ•Šκ³  ν•œ λ²ˆμ— λ‹€μˆ˜μ˜ νŽ˜μ΄μ§€μ— μ ‘κ·Όν•˜λŠ” ν…Œμ΄λΈ” ν’€ μŠ€μΊ” λ°©μ‹μœΌλ‘œ μˆ˜ν–‰λ©λ‹ˆλ‹€.
  • μ†Œμš” μ‹œκ°„μ€ 3.5초 -> 1.2초둜 κ°μ†Œ

 

7. μž‘μ€ ν…Œμ΄λΈ”μ΄ λ¨Όμ € 쑰인에 μ°Έμ—¬ν•˜λŠ”(λ“œλΌμ΄λΉ™ ν…Œμ΄λΈ”) λ‚˜μœ SQL λ¬Έ

λΆ€μ„œ ν…Œμ΄λΈ”: 9건, λΆ€μ„œμ‚¬μ›_맀핑 ν…Œμ΄λΈ”: 33만건

 

νŠœλ‹ μ „ SQL, μ‹€ν–‰ κ³„νš

SELECT 맀핑.μ‚¬μ›λ²ˆν˜Έ, λΆ€μ„œ.λΆ€μ„œλ²ˆν˜Έ
FROM λΆ€μ„œμ‚¬μ›_맀핑 맀핑
JOIN λΆ€μ„œ ON 맀핑.λΆ€μ„œλ²ˆν˜Έ = λΆ€μ„œ.λΆ€μ„œλ²ˆν˜Έ
WHERE 맀핑.μ‹œμž‘μΌμž >= '2002-03-01';

  • λ“œλΌμ΄λΉ™ ν…Œμ΄λΈ”(λΆ€μ„œ), λ“œλ¦¬λΈ ν…Œμ΄λΈ”(λΆ€μ„œμ‚¬μ›_맀핑) 쀑첩 루프 쑰인을 μˆ˜ν–‰ν•©λ‹ˆλ‹€.
  • λΆ€μ„œμ‚¬μ›_맀핑 ν…Œμ΄λΈ”μ˜ rows ν•­λͺ©μ˜ 40355 μˆ˜μΉ˜λŠ”, SQL 문을 μˆ˜ν–‰ν•˜κ³ μž μ‘°μ‚¬ν•œ ν–‰μ˜ 예츑 건수둜, 인덱슀 μŠ€μΊ”μ„ ν•˜κ³  랜덀 μ•‘μ„ΈμŠ€λ‘œ ν…Œμ΄λΈ”μ— μ ‘κ·Όν•˜κ²Œ λ©λ‹ˆλ‹€. λ˜ν•œ MySQL μ—”μ§„μœΌλ‘œ κ°€μ Έμ˜¨ λͺ¨λ“  데이터에 λŒ€ν•΄ WHERE 절의 ν•„ν„° 쑰건 (μ‹œμž‘μΌμž >= ...) 을 μˆ˜ν–‰ν•©λ‹ˆλ‹€.

νŠœλ‹ ν›„ SQL, μ‹€ν–‰ κ³„νš

SELECT STRAIGHT_JOIN 맀핑.μ‚¬μ›λ²ˆν˜Έ, λΆ€μ„œ.λΆ€μ„œλ²ˆν˜Έ
FROM λΆ€μ„œμ‚¬μ›_맀핑 맀핑
JOIN λΆ€μ„œ ON 맀핑.λΆ€μ„œλ²ˆν˜Έ = λΆ€μ„œ.λΆ€μ„œλ²ˆν˜Έ
WHERE 맀핑.μ‹œμž‘μΌμž >= '2002-03-01';

  • μƒλŒ€μ μœΌλ‘œ 규λͺ¨κ°€ 큰 λΆ€μ„œμ‚¬μ›_맀핑 ν…Œμ΄λΈ”μ˜ 맀핑.μ‹œμž‘μΌμž >= '2002-03-01' μ‘°κ±΄μ ˆμ„ λ¨Όμ € μ μš©ν•œλ‹€λ©΄, 쑰인할 λ•Œ 비ꡐ λŒ€μƒμ΄ 쀄어듀 κ²ƒμž…λ‹ˆλ‹€. (ν•΄λ‹Ή λ°μ΄ν„°λŠ” μ•½ 1300건)
  • λΆ€μ„œμ‚¬μ›_맀핑 ν…Œμ΄λΈ”μ„ λ¨Όμ € μ ‘κ·Ό(λ“œλΌμ΄λΉ™)ν•˜μ—¬ ν…Œμ΄λΈ” ν’€ μŠ€μΊ”μœΌλ‘œ μ²˜λ¦¬ν•˜κ³ , λΆ€μ„œ ν…Œμ΄λΈ”μ—λŠ” PK둜 μ ‘κ·Όν•˜μ—¬ 1개의 λ°μ΄ν„°λ§Œ μ ‘κ·Όν•˜λŠ” μ‹μœΌλ‘œ μˆ˜ν–‰λ©λ‹ˆλ‹€.
  • κ³ λ €ν•΄μ•Ό ν•  점은, μ‹œμž‘μΌμž 열이 λ²”μœ„ 쑰건으둜 μž‘μ„±λ˜λŠ”μ§€, κ·Έ λ²”μœ„μ— ν•΄λ‹Ήν•˜λŠ” 데이터가 μœ„μ—μ„œ μ„€λͺ…ν–ˆλ˜ 인덱슀 손읡뢄기점을 λ„˜κΈ°μ§€ μ•ŠλŠ” μ •λ„μ˜ λΉ„μœ¨μ΄λΌλ©΄ 인덱슀λ₯Ό μƒμ„±ν•˜λŠ” 것이 더 효율적일 수 μžˆμŠ΅λ‹ˆλ‹€.

 

8. 메인 ν…Œμ΄λΈ”μ— 계속 μ˜μ‘΄ν•˜λŠ” λ‚˜μœ SQL λ¬Έ

사원 ν…Œμ΄λΈ”: 30만건, κΈ‰μ—¬ ν…Œμ΄λΈ”: 280만건

 

νŠœλ‹ μ „ SQL, μ‹€ν–‰ κ³„νš

SELECT 사원.μ‚¬μ›λ²ˆν˜Έ, 사원.이름, 사원.μ„±
FROM 사원
WHERE μ‚¬μ›λ²ˆν˜Έ > 450000
  AND (
    	SELECT MAX(연봉) 
        FROM κΈ‰μ—¬ 
        WHERE μ‚¬μ›λ²ˆν˜Έ = 사원.μ‚¬μ›λ²ˆν˜Έ
  ) > 100000;

  • 1: 사원 ν…Œμ΄λΈ”μ˜ PKλ₯Ό ν™œμš©ν•˜μ—¬ λ²”μœ„ μŠ€μΊ”μ„ μˆ˜ν–‰ν•©λ‹ˆλ‹€.
  • 2: κΈ‰μ—¬ ν…Œμ΄λΈ”μ— μ ‘κ·Όν•˜λŠ”λ°, μ™ΈλΆ€μ˜ 사원 ν…Œμ΄λΈ”λ‘œλΆ€ν„° μ‘°κ±΄μ ˆμ„ 전달받아 μˆ˜ν–‰ν•΄μ•Ό ν•˜λŠ” μ˜μ‘΄μ„±μ„ 가진 μ„œλΈŒμΏΌλ¦¬μž…λ‹ˆλ‹€. 그리고 κΈ‰μ—¬ ν…Œμ΄λΈ”μ€ PKλ₯Ό ν™œμš©ν•©λ‹ˆλ‹€.
πŸ’‘ 보톡 μ‹€ν–‰ κ³„νšμ˜ select_type ν•­λͺ©μ— DEPENDENTλΌλŠ” ν‚€μ›Œλ“œκ°€ 있으면, μ™ΈλΆ€ ν…Œμ΄λΈ”μ—μ„œ μ‘°κ±΄μ ˆμ„ 받은 λ’€ μ²˜λ¦¬λ˜μ–΄μ•Ό ν•˜λ―€λ‘œ νŠœλ‹ λŒ€μƒμœΌλ‘œ κ³ λ €ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
πŸ’‘ μ„œλΈŒμΏΌλ¦¬ vs 쑰인
ν•„μž κ²½ν—˜μƒ μ„œλΈŒμΏΌλ¦¬λ³΄λ‹€λŠ” 쑰인으둜 μˆ˜ν–‰ν•˜λŠ” 편이 μ„±λŠ₯ μΈ‘λ©΄μ—μ„œ μœ λ¦¬ν•  κ°€λŠ₯성이 λ†’μŠ΅λ‹ˆλ‹€.

 

νŠœλ‹ ν›„ SQL, μ‹€ν–‰ κ³„νš

SELECT 사원.μ‚¬μ›λ²ˆν˜Έ, 사원.이름, 사원.μ„±
FROM 사원 JOIN κΈ‰μ—¬ ON 사원.μ‚¬μ›λ²ˆν˜Έ = κΈ‰μ—¬.μ‚¬μ›λ²ˆν˜Έ
WHERE 사원.μ‚¬μ›λ²ˆν˜Έ > 450000
GROUP BY 사원.μ‚¬μ›λ²ˆν˜Έ
HAVING MAX(κΈ‰μ—¬.연봉) > 100000;

  • WHERE 절의 μ„œλΈŒμΏΌλ¦¬λ₯Ό 쑰인으둜 λ³€κ²½ν•˜μ—¬ GROUP BY, HAVING μ ˆμ„ 톡해 νŠœλ‹ μ „ 그룹별 μ΅œλŒ“κ°’μ„ κ³„μ‚°ν•˜λ„λ‘ κ°œμ„ ν•©λ‹ˆλ‹€.
  • κΈ‰μ—¬ ν…Œμ΄λΈ”μ˜ DEPENDENT SUBQUERY 방식은 제거되고, λ‹¨μˆœ μ‘°μΈν•˜λŠ” λ°©μ‹μœΌλ‘œ 효율 ν–₯상
  • rowsλŠ” μ˜ˆμΈ‘κ°’μ΄λ―€λ‘œ λ‹¨μˆœνžˆ rows λ°μ΄ν„°λ‘œ νŠœλ‹ 성곡 μ—¬λΆ€λ₯Ό νŒλ‹¨ν•˜κΈ°λŠ” μ–΄λ ΅μŠ΅λ‹ˆλ‹€.

 

μ—¬λŸ¬ 상황에 λŒ€ν•΄ SQL νŠœλ‹μ„ 진행해 λ³΄μ•˜λŠ”λ°μš”, μ‹€μ œλ‘œ 일을 ν•˜λ©΄μ„œ λΉ„μŠ·ν•œ 사둀λ₯Ό κ²ͺμ—ˆλ˜ μΌ€μ΄μŠ€λ„ μžˆμ—ˆκ³ , 이둠적으둜만 μ•Œκ³  μžˆμ—ˆλ˜ λ‚΄μš©μ΄λ‚˜, μ „ν˜€ λͺ°λžλ˜ λ‚΄μš©μ— λŒ€ν•΄μ„œλ„ ν•™μŠ΅ν•  수 μžˆμ—ˆμŠ΅λ‹ˆλ‹€.

 

λ‹€μŒμ€ 쑰금 더 싀무에 κ°€κΉŒμš΄(?) λ³΅μž‘ν•œ 쿼리λ₯Ό ν† λŒ€λ‘œ 인덱슀 λ³€κ²½, ν…Œμ΄λΈ” ꡬ쑰 λ³€κ²½ 및 SQL μž¬μž‘μ„± λ“± 쿼리 νŠœλ‹μ„ μˆ˜ν–‰ν•  μ˜ˆμ •μž…λ‹ˆλ‹€.

 

 

λ°˜μ‘ν˜•

λŒ“κΈ€