Home > Backend Development > πŸ“š[Backend Development] λ¬΄ν•œ Depth λŒ“κΈ€ μ •λ ¬ - Path Enumeration(경둜 μ—΄κ±°) 방식과 인덱슀 ν™œμš©

πŸ“š[Backend Development] λ¬΄ν•œ Depth λŒ“κΈ€ μ •λ ¬ - Path Enumeration(경둜 μ—΄κ±°) 방식과 인덱슀 ν™œμš©
Backend Ddevelopment

β€œπŸ“š[Backend Development] Path Enumeration λ°©μ‹μ—μ„œ λŒ“κΈ€μ˜ 경둜(Path) κ²°μ • κ³Όμ •.”

βœ…1️⃣ λŒ“κΈ€ 트리 κ΅¬μ‘°μ—μ„œ μƒˆλ‘œμš΄ λŒ“κΈ€μ˜ path κ²°μ •ν•˜κΈ°

  • Path Enumeration(경둜 μ—΄κ±°) 방식을 μ‚¬μš©ν•  λ•Œ, μƒˆλ‘œμš΄ λŒ“κΈ€μ΄ 좔가될 경우 ν•΄λ‹Ή λŒ“κΈ€μ˜ pathλ₯Ό κ²°μ •ν•˜λŠ” 과정이 μ€‘μš”ν•©λ‹ˆλ‹€.
  • λŒ“κΈ€μ€ λΆ€λͺ¨ λŒ“κΈ€μ˜ pathλ₯Ό μƒμ†λ°›μœΌλ©°, κ°€μž₯ λ§ˆμ§€λ§‰μ— μžˆλŠ” λŒ“κΈ€μ˜ pathλ₯Ό κΈ°μ€€μœΌλ‘œ μƒˆλ‘œμš΄ pathκ°€ μƒμ„±λ©λ‹ˆλ‹€.

πŸ“Œ1️⃣ κΈ°μ‘΄ λŒ“κΈ€ 트리 ꡬ쑰.

  • μƒˆλ‘œμš΄ λŒ“κΈ€μ΄ μΆ”κ°€λ˜κΈ° μ „μ˜ μƒνƒœλ₯Ό ν™•μΈν•©λ‹ˆλ‹€.
    • μ΅œμƒμœ„ λŒ“κΈ€ 00a0zκ°€ 있고, ν•˜μœ„ λŒ“κΈ€λ“€μ΄ κ³„μΈ΅μ μœΌλ‘œ μ‘΄μž¬ν•©λ‹ˆλ‹€.
    • pathλŠ” λΆ€λͺ¨ λŒ“κΈ€μ˜ pathλ₯Ό 상속받아 μƒμ„±λ˜λ©°, λŒ“κΈ€μ΄ μΆ”κ°€λ μˆ˜λ‘ 순차적으둜 μ¦κ°€ν•©λ‹ˆλ‹€.

πŸ“Œ2️⃣ μƒˆλ‘œμš΄ λŒ“κΈ€ μΆ”κ°€ μš”μ²­.

  • μ–΄λ–€ μ‚¬μš©μ‚¬μš©μžκ°€ 00a0z λŒ“κΈ€μ˜ ν•˜μœ„μ— μƒˆλ‘œμš΄ λŒ“κΈ€μ„ μΆ”κ°€ν•˜λ €κ³  ν•©λ‹ˆλ‹€.
  • ν•˜μ§€λ§Œ, ν˜„μž¬ 00a0z의 ν•˜μœ„ λŒ“κΈ€λ“€μ΄ μ‘΄μž¬ν•˜κΈ° λ•Œλ¬Έμ— μƒˆλ‘œμš΄ pathλ₯Ό κ²°μ •ν•΄μ•Ό ν•©λ‹ˆλ‹€.
    - ν˜„μž¬ 00a0z의 ν•˜μœ„ λŒ“κΈ€ 쀑 κ°€μž₯ 큰 path(childernTopPath)λ₯Ό μ°Ύμ•„μ•Ό ν•©λ‹ˆλ‹€.

πŸ“Œ3️⃣ childrenTopPath μ°ΎκΈ°

  • μƒˆλ‘œμš΄ λŒ“κΈ€μ„ μΆ”κ°€ν•  λ•ŒλŠ”, ν˜„μž¬ μ‘΄μž¬ν•˜λŠ” ν•˜μœ„ λŒ“κΈ€ 쀑 κ°€μž₯ 큰 path(childrenTopPath)λ₯Ό μ°Ύκ³  ν•΄λ‹Ή 값에 +1을 ν•˜μ—¬ μƒˆλ‘œμš΄ λŒ“κΈ€μ˜ pathλ₯Ό μƒμ„±ν•©λ‹ˆλ‹€..
    • ν˜„μž¬ 00a0z의 ν•˜μœ„ λŒ“κΈ€ μ€‘μ—μ„œ κ°€μž₯ 큰 pathλŠ” 00a0z 00002μž…λ‹ˆλ‹€.
    • λ”°λΌμ„œ, μƒˆλ‘œμš΄ λŒ“κΈ€μ˜ pathλŠ” 00a0z 00003이 λ©λ‹ˆλ‹€.

βœ…2️⃣ Path Enumeration λ°©μ‹μ—μ„œ 인덱슀 ν™œμš©

  • Path Enumeration λ°©μ‹μ—μ„œλŠ” λΉ λ₯Έ 검색을 μœ„ν•΄ 인덱슀λ₯Ό ν™œμš©ν•  수 μ•˜μŠ΅λ‹ˆλ‹€.
  • 특히 descendantsTopPathλ₯Ό 찾을 λ•Œ Backward Index Scan을 μ‚¬μš©ν•˜λ©΄ λΉ λ₯Έ μ‘°νšŒκ°€ κ°€λŠ₯ν•©λ‹ˆλ‹€.

πŸ“Œ1️⃣ descendantsTopPathλ₯Ό μ°ΎλŠ” κ³Όμ •.

  • μƒˆλ‘œμš΄ λŒ“κΈ€μ„ μΆ”κ°€ν•  λ•Œ, κ°€μž₯ 큰 descendantsTopPathλ₯Ό μ°Ύμ•„μ•Ό ν•©λ‹ˆλ‹€.
  • path μ •λ ¬ μƒνƒœλ₯Ό μœ μ§€ν•˜λ©΄μ„œ μ—­μˆœμœΌλ‘œ 인덱슀λ₯Ό νƒμƒ‰ν•˜λ©΄, κ°€μž₯ 큰 path(descendantsTopPath)λ₯Ό λΉ λ₯΄κ²Œ 찾을 수 μžˆμŠ΅λ‹ˆλ‹€.
  • Backward Index Scan을 ν™œμš©ν•˜λ©΄ 둜그 μ‹œκ°„(log time) 내에 μ‘°νšŒκ°€ κ°€λŠ₯ν•©λ‹ˆλ‹€.
  • λ¨Όμ € μ•„λž˜μ˜ 쿼리λ₯Ό μ΄μš©ν•˜μ—¬ descendantsTopPathλ₯Ό DBμ—μ„œ 찾을 수 μžˆμŠ΅λ‹ˆλ‹€:
SELECT path FROM comment_v2
WHERE article_id = {article_id}
AND path > {parentPath} // parent 본인은 미포함 검색 쑰건
AND path like {parentPath}% // parentPathλ₯Ό prefix둜 ν•˜λŠ” λͺ¨λ“  μžμ† 검색 쑰건
ORDER BY path DESC LIMIT 1; // 쑰회 κ²°κ³Όμ—μ„œ κ°€μž₯ 큰 path

πŸ“Œ2️⃣ Backward Index Scan ν™œμš©

  • path ν•„λ“œμ— μ˜€λ¦„μ°¨μˆœ(ASC) μΈλ±μŠ€κ°€ μ„€μ •λ˜μ–΄ μžˆμ–΄λ„, λ‚΄λ¦Όμ°¨μˆœ(DESC) 정렬을 톡해 κ°€μž₯ 큰 pathλ₯Ό λΉ λ₯΄κ²Œ 찾을 수 μžˆμŠ΅λ‹ˆλ‹€.
  • 인덱슀 트리(Leaf Node) κ°„μ˜ μ–‘λ°©ν–₯ 포인터λ₯Ό ν™œμš©ν•˜μ—¬ μ—­μˆœ 검색을 μˆ˜ν–‰ν•©λ‹ˆλ‹€.
  • μ—­μˆœμœΌλ‘œ μŠ€μΊ”ν•˜μ—¬ LIMIT 1을 μ μš©ν•˜λ©΄ κ°€μž₯ 큰 pathλ₯Ό λΉ λ₯΄κ²Œ 찾을 수 μžˆμŠ΅λ‹ˆλ‹€.

βœ…3️⃣ MySQL Query Plan 뢄석 (EXPLAIN)

  • MySQLμ—μ„œ descendantsTopPathλ₯Ό μ°ΎλŠ” 쿼리의 μ‹€ν–‰ κ³„νšμ„ λΆ„μ„ν•΄λ΄…λ‹ˆλ‹€.
EXPLAIN SELECT path FROM comment_v2
WHERE article_id = 1
AND path > '00a0z'
AND path LIKE '00a0z%'
ORDER BY path DESC LIMIT 1;

πŸ“Œ EXPLAIN 뢄석 κ²°κ³Ό

    1. idx_article_id_path 인덱슀 μ‚¬μš©λ¨
      • β†’ 인덱슀λ₯Ό ν™œμš©ν•˜μ—¬ λΉ λ₯΄κ²Œ pathλ₯Ό μ‘°νšŒν•  수 있음
    1. Backward Index Scan 적용됨
      • β†’ ORDER BY path DESC LIMIT 1을 톡해 μ—­μˆœ 탐색 μˆ˜ν–‰
    1. Using Index 적용됨
      • β†’ μΈλ±μŠ€μ—μ„œ 직접 데이터λ₯Ό κ°€μ Έμ˜€κΈ° λ•Œλ¬Έμ— μ„±λŠ₯ μ΅œμ ν™” κ°€λŠ₯

βœ…4️⃣ κ²°λ‘ 

πŸš€ Path Enumeration(경둜 μ—΄κ±°) λ°©μ‹μ—μ„œ λŒ“κΈ€μ„ μΆ”κ°€ν•  λ•Œ, pathλ₯Ό κ²°μ •ν•˜λŠ” κ³Όμ •.

  • βœ… κ°€μž₯ 큰 childrenTopPathλ₯Ό μ°Ύκ³ , +1을 ν•˜μ—¬ μƒˆλ‘œμš΄ pathλ₯Ό 생성
  • βœ… descendantsTopPathλ₯Ό μ°Ύμ•„ 계측 ꡬ쑰λ₯Ό μœ μ§€ν•˜λ©΄μ„œ λŒ“κΈ€μ„ μ •λ ¬
  • βœ… MySQL의 Backward Index Scan을 ν™œμš©ν•˜μ—¬ λΉ λ₯΄κ²Œ descendantsTopPathλ₯Ό 검색
  • βœ… λŒ€κ·œλͺ¨ λ°μ΄ν„°μ—μ„œλ„ 인덱슀λ₯Ό ν™œμš©ν•˜μ—¬ λΉ λ₯Έ μ„±λŠ₯을 μœ μ§€

πŸ“Œ Path Enumeration 방식을 μ‚¬μš©ν•  λ•ŒλŠ”, Backward Index Scan을 ν™œμš©ν•˜μ—¬ 졜적의 μ„±λŠ₯을 보μž₯ν•˜λŠ” 것이 μ€‘μš”ν•©λ‹ˆλ‹€.