Home > DB > πŸ’Ύ[Database] Covering IndexλŠ” λ¬΄μ—‡μΌκΉŒμš”?

πŸ’Ύ[Database] Covering IndexλŠ” λ¬΄μ—‡μΌκΉŒμš”?
Database Native SQL Query MySQL

β€œπŸ’Ύ[Database] Covering IndexλŠ” λ¬΄μ—‡μΌκΉŒμš”?”

🍎 Intro.

  • 쿼리가 μš”μ²­ν•˜λŠ” λͺ¨λ“  데이터가 μΈλ±μŠ€μ— ν¬ν•¨λ˜μ–΄ μžˆμ–΄, ν…Œμ΄λΈ”μ— μ‹€μ œ 데이터λ₯Ό μ‘°νšŒν•˜μ§€ μ•Šκ³ λ„ κ²°κ³Όλ₯Ό λ°˜ν™˜ν•  수 μžˆλŠ” 인덱슀λ₯Ό λ§ν•©λ‹ˆλ‹€.
  • 즉, 인덱슀만으둜 쿼리λ₯Ό μ²˜λ¦¬ν•  수 μžˆλŠ” 경우λ₯Ό Covering Index라고 λΆ€λ¦…λ‹ˆλ‹€.
    • μ΄λŠ” λ°μ΄ν„°λ² μ΄μŠ€μ˜ μ„±λŠ₯을 크게 ν–₯μƒμ‹œν‚¬ 수 μžˆμŠ΅λ‹ˆλ‹€.

βœ…1️⃣ Covering Index의 λ™μž‘ 방식.

  • 1. 일반적인 인덱슀 μ‚¬μš©:
    • 쿼리가 μ‹€ν–‰λ˜λ©΄ λ¨Όμ € 인덱슀λ₯Ό νƒμƒ‰ν•˜μ—¬ λ°μ΄ν„°μ˜ μœ„μΉ˜λ₯Ό μ°Ύκ³ , 이후 ν…Œμ΄λΈ”μ˜ 데이터λ₯Ό μ‘°νšŒν•©λ‹ˆλ‹€.
      • 이λ₯Ό β€œμΈλ±μŠ€ 룩업(Index Lookup)”이라고 ν•©λ‹ˆλ‹€.
  • 2. Covering Index μ‚¬μš©:
    • 쿼리가 μš”μ²­ν•˜λŠ” λͺ¨λ“  데이터가 μΈλ±μŠ€μ— ν¬ν•¨λ˜μ–΄ 있으면, 인덱슀만으둜 κ²°κ³Όλ₯Ό λ°˜ν™˜ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
    • ν…Œμ΄λΈ” 데이터λ₯Ό μ‘°νšŒν•  ν•„μš”κ°€ μ—†μœΌλ―€λ‘œ λ””μŠ€ν¬ I/Oλ₯Ό 쀄이고 μ„±λŠ₯을 κ°œμ„ ν•©λ‹ˆλ‹€.

βœ…2️⃣ Covering Index의 쑰건.

  • 쿼리의 SELECTμ ˆμ— ν¬ν•¨λœ 컬럼과 WHERE, ORDER BY λ˜λŠ” GROUP BY에 μ‚¬μš©λœ 컬럼이 λͺ¨λ‘ μΈλ±μŠ€μ— ν¬ν•¨λ˜μ–΄ μžˆμ–΄μ•Ό ν•©λ‹ˆλ‹€.
    • μ΄λŸ¬ν•œ 인덱슀λ₯Ό β€œCovering Index”라고 λΆ€λ¦…λ‹ˆλ‹€.

βœ…3️⃣ Covering Index의 예제.

1️⃣ ν…Œμ΄λΈ” 생성 및 데이터 μ‚½μž…

CREATE TABLE article (
    article_id INT NOT NULL,
    board_id INT NOT NULL,
    created_at DATETIME NOT NULL,
    title VARCHAR(255),
    content TEXT,
    PRIMARY KEY (article_id)
);

2️⃣ 인덱슀 생성.

CREATE INDEX idx_board_created_at ON article (board_id, created_at);

3️⃣ Covering Index ν™œμš© 쿼리.

EXPLAIN
SELECT board_id, created_at
FROM article
WHERE board_id = 1
ORDER BY created_at DESC;
  • 인덱슀 λ™μž‘ μ„€λͺ…:
    • μΏΌλ¦¬μ—μ„œ μš”μ²­ν•œ 컬럼(board_id, created_at)이 인덱슀 idx_board_created_at에 λͺ¨λ‘ ν¬ν•¨λ˜μ–΄ μžˆμœΌλ―€λ‘œ:
      • Covering Indexκ°€ μ μš©λ©λ‹ˆλ‹€.
      • MySQL은 ν…Œμ΄λΈ”μ˜ μ‹€μ œ 데이터λ₯Ό μ‘°νšŒν•˜μ§€ μ•Šκ³  인덱슀만으둜 κ²°κ³Όλ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.

βœ…4️⃣ Covering Index의 μž₯점.

  • 1. μ„±λŠ₯ ν–₯상:
    • 쿼리가 μš”μ²­ν•œ 데이터가 λͺ¨λ‘ μΈλ±μŠ€μ— μ΄ˆν•¨λ˜μ–΄ μžˆμœΌλ―€λ‘œ ν…Œμ΄λΈ”μ˜ 데이터λ₯Ό 읽지 μ•Šμ•„λ„ λ©λ‹ˆλ‹€.
    • λ””μŠ€ν¬ I/Oκ°€ 쀄어듀고, 쿼리 μ‹€ν–‰ μ‹œκ°„μ΄ 크게 λ‹¨μΆ•λ©λ‹ˆλ‹€.
  • 2. 효율적인 μŠ€ν† λ¦¬μ§€ ν™œμš©:
    • ν…Œμ΄λΈ” 데이터λ₯Ό 읽지 μ•Šκ³ , 인덱슀만으둜 μ²˜λ¦¬λ˜λ―€λ‘œ 더 적은 μžμ›μ„ μ‚¬μš©ν•©λ‹ˆλ‹€.
  • 3. νŠΉμ • 쿼리에 μ΅œμ ν™” κ°€λŠ₯:
    • νŠΉμ • μΏΌλ¦¬μ—μ„œ 자주 μ‚¬μš©ν•˜λŠ” 컬럼만 ν¬ν•¨ν•˜μ—¬ μ„€κ³„ν•˜λ©΄, 쿼리 μ„±λŠ₯을 μ΅œμ ν™”ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

βœ…5️⃣ Covering Index의 ν•œκ³„.

  • 1. 인덱슀 크기 증가:
    • μΈλ±μŠ€μ— λ§Žμ€ μ»¬λŸΌμ„ μΆ”κ°€ν•˜λ©΄, 인덱슀 크기가 컀져 μ‚½μž…/μ‚­μ œ μ„±λŠ₯이 μ €ν•˜λ  수 μžˆμŠ΅λ‹ˆλ‹€.
  • 2. λͺ¨λ“  쿼리에 적용 λΆˆκ°€λŠ₯:
    • SELECT *처럼 ν…Œμ΄λΈ”μ— λͺ¨λ“  μ»¬λŸΌμ„ μš”μ²­ν•˜λŠ” μΏΌλ¦¬μ—λŠ” μ μš©λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
    • 쿼리에 ν¬ν•¨λ˜μ§€ μ•Šμ€ μ»¬λŸΌμ€ μ—¬μ „νžˆ μΌ€μ΄λΈ”μ—μ„œ μ‘°νšŒν•΄μ•Ό ν•©λ‹ˆλ‹€.
  • 3. λ³΅μž‘ν•œ 섀계 ν•„μš”:
    • νŠΉμ • 쿼리에 맞좘 컀버링 인덱슀λ₯Ό μ„€κ³„ν•˜λ €λ©΄ 쿼리 뢄석이 ν•„μš”ν•˜λ©°, 인덱슀 관리가 λ³΅μž‘ν•΄μ§ˆ 수 μžˆμŠ΅λ‹ˆλ‹€.

βœ…6️⃣ Covering Indexκ°€ μ ν•©ν•œ 경우.

  • 1. 읽기(SELECT) μž‘μ—…μ΄ λ§Žμ€ 경우:
    • 읽기 μ„±λŠ₯이 μ€‘μš”ν•œ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ—μ„œ μœ μš©ν•©λ‹ˆλ‹€.
  • 2. 자주 μ‚¬μš©λ˜λŠ” νŠΉμ • 쿼리가 μžˆλŠ” 경우:
    • 쿼리 νŒ¨ν„΄μ„ λΆ„μ„ν•˜μ—¬, ν•„μš”ν•œ 컬럼만 ν¬ν•¨ν•˜λŠ” 컀버링 인덱슀λ₯Ό μ„€κ³„ν•©λ‹ˆλ‹€.
  • 3. λ²”μœ„ 검색과 정렬이 μ€‘μš”ν•œ 경우:
    • 예: λ‚ μ§œλ³„ μ •λ ¬, νŠΉμ • 쑰건에 따라 ν•„ν„°λ§λœ κ²°κ³Ό 쑰회 λ“±.

βœ…7️⃣ Covering Inde와 EXPLAIN

  • EXPLAIN을 μ‚¬μš©ν•˜λ©΄ μΏΌλ¦¬μ—μ„œ 컀버링 μΈλ±μŠ€κ°€ μ μš©λ˜μ—ˆλŠ”μ§€ 확인할 수 μžˆμŠ΅λ‹ˆλ‹€.
  • EXPLAIN κ²°κ³Όμ—μ„œ 확인 방법:
    • Extra μ—΄(Column)에 Using indexκ°€ ν‘œμ‹œλ˜λ©΄ Covering Indexκ°€ 적용된 κ²ƒμž…λ‹ˆλ‹€.
  • 예제:
EXPLAIN
SELECT board_id, created_at
FROM article
WHERE board_id = 1
ORDER BY created_at DESC;
id select_type table type key key_len ref rows Extra
1 SIMPLE article index idx_board_created_at 8 const 100 Using Index
  • κ²°κ³Ό 해석:
    • Extra에 Using indexκ°€ ν‘œμ‹œλ˜λ©΄, 쿼리가 컀버링 인덱슀λ₯Ό μ‚¬μš©ν–ˆμŒμ„ μ˜λ―Έν•©λ‹ˆλ‹€.

πŸš€ 정리.

  • Covering IndexλŠ” 쿼리가 μš”μ²­ν•˜λŠ” λͺ¨λ“  데이터가 μΈλ±μŠ€μ— ν¬ν•¨λœ 경우, ν…Œμ΄λΈ”μ„ μ‘°νšŒν•˜μ§€ μ•Šκ³ λ„ 쿼리λ₯Ό μ²˜λ¦¬ν•  수 μžˆλŠ” μΈλ±μŠ€μž…λ‹ˆλ‹€.
  • μž₯점 : λ””μŠ€ν¬ I/O κ°μ†Œ, 쿼리 μ„±λŠ₯ ν–₯상.
  • 단점 : 인덱슀 크기 증가, λͺ¨λ“  쿼리에 적용 λΆˆκ°€λŠ₯.
  • MySQLμ—μ„œ EXPLAIN으둜 인덱슀 μ‚¬μš© μ—¬λΆ€λ₯Ό 확인할 수 있으며, Extra에 Using indexκ°€ ν‘œμ‹œλ˜λ©΄ Covering Indexκ°€ 적용된 κ²ƒμž…λ‹ˆλ‹€.