Home > Backend Development > πŸ“š[Backend Development] λ¬΄ν•œ Depth λŒ“κΈ€ 쑰회 - Path Enumeration & 인덱슀 μ΅œμ ν™”

πŸ“š[Backend Development] λ¬΄ν•œ Depth λŒ“κΈ€ 쑰회 - Path Enumeration & 인덱슀 μ΅œμ ν™”
Backend Ddevelopment

β€œπŸ“š[Backend Development] λ¬΄ν•œ Depth λŒ“κΈ€ 쑰회 - Path Enumeration & 인덱슀 μ΅œμ ν™”β€

βœ…1️⃣ Path Enumeration λ°©μ‹μ—μ„œ λŒ“κΈ€ path κ²°μ •

  • Path Enumeration(경둜 μ—΄κ±°) 방식은 각 λŒ“κΈ€μ˜ pathλ₯Ό κ³„μΈ΅μ μœΌλ‘œ μ €μž₯ν•˜μ—¬ μ •λ ¬ 및 검색을 λΉ λ₯΄κ²Œ μˆ˜ν–‰ν•˜λŠ” κΈ°λ²•μž…λ‹ˆλ‹€.
  • λŒ“κΈ€μ΄ 좔가될 λ•Œ λΆ€λͺ¨ λŒ“κΈ€μ˜ pathλ₯Ό 상속받고, ν•˜μœ„ λŒ“κΈ€ 쀑 κ°€μž₯ 큰 pathλ₯Ό κΈ°μ€€μœΌλ‘œ μƒˆλ‘œμš΄ pathκ°€ κ²°μ •λ©λ‹ˆλ‹€.

πŸ“Œ1️⃣ ν˜„μž¬ λŒ“κΈ€ 트리 ꡬ쑰

  • ν˜„μž¬ λŒ“κΈ€ 트리의 pathλŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.
    • 00a0z λŒ“κΈ€ μ•„λž˜μ— κ³„μΈ΅μ μœΌλ‘œ μ •λ ¬λœ ν•˜μœ„ λŒ“κΈ€λ“€μ΄ μžˆμŠ΅λ‹ˆλ‹€.
    • λŒ“κΈ€μ˜ pathλŠ” λΆ€λͺ¨ λŒ“κΈ€μ˜ pathλ₯Ό 상속받아 00000, 00001, 00002 λ“±μœΌλ‘œ μΆ”κ°€λ©λ‹ˆλ‹€.

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

  • μ‚¬μš©μžκ°€ 00a0z λŒ“κΈ€μ˜ ν•˜μœ„μ— μƒˆλ‘œμš΄ λŒ“κΈ€μ„ μΆ”κ°€ν•˜λ €κ³  ν•©λ‹ˆλ‹€.
    • μƒˆλ‘œμš΄ λŒ“κΈ€μ΄ 좔가될 pathλ₯Ό κ²°μ •ν•΄μ•Ό ν•©λ‹ˆλ‹€.
    • κΈ°μ‘΄ λŒ“κΈ€ 쀑 κ°€μž₯ 큰 pathλ₯Ό μ°Ύμ•„ 이λ₯Ό κΈ°μ€€μœΌλ‘œ +1을 μ μš©ν•˜μ—¬ μƒˆλ‘œμš΄ pathλ₯Ό μƒμ„±ν•©λ‹ˆλ‹€.

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

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

πŸ“Œ4️⃣ descendantsTopPathλ₯Ό κ³ λ €ν•œ μ΅œμ’… path κ²°μ •

  • ν•˜μ§€λ§Œ μžμ‹ λŒ“κΈ€μ΄ μ‘΄μž¬ν•˜λŠ” 경우, λ‹¨μˆœνžˆ childrenTopPath만 κ³ λ €ν•˜λ©΄ μ•ˆ λ©λ‹ˆλ‹€. κ°€μž₯ κΉŠμ€ depthκΉŒμ§€ κ³ λ €ν•œ descendantsTopPathλ₯Ό μ°Ύμ•„μ•Ό ν•©λ‹ˆλ‹€.
    • descendantsTopPathλŠ” λΆ€λͺ¨ λŒ“κΈ€μ„ ν¬ν•¨ν•œ λͺ¨λ“  μžμ‹ λŒ“κΈ€ 쀑 κ°€μž₯ 큰 pathμž…λ‹ˆλ‹€.
    • childrenTopPath = 00a0z 00002μ΄λ―€λ‘œ, μƒˆλ‘œμš΄ λŒ“κΈ€μ˜ pathλŠ” 00a0z 00003이 λ©λ‹ˆλ‹€.

βœ…2️⃣ MySQLμ—μ„œ descendantsTopPath μ°ΎκΈ°.

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

πŸ“Œ1️⃣ descendantsTopPathλ₯Ό μ°ΎλŠ” SQL

SELECT path FROM comment_v2
WHERE article_id = {article_id}
AND path > {parentPath} -- λΆ€λͺ¨ λŒ“κΈ€ μ œμ™Έ
AND path LIKE {parentPath}% -- λΆ€λͺ¨ λŒ“κΈ€ prefixλ₯Ό ν¬ν•¨ν•˜λŠ” λͺ¨λ“  μžμ‹ λŒ“κΈ€ 쑰회
ORDER BY path DESC LIMIT 1; -- κ°€μž₯ 큰 pathλ₯Ό μ°ΎκΈ° μœ„ν•΄ λ‚΄λ¦Όμ°¨μˆœ μ •λ ¬
  • κ°€μž₯ 큰 path(descendantsTopPath)λ₯Ό 찾을 λ•Œ λ‚΄λ¦Όμ°¨μˆœ 정렬을 ν™œμš©ν•©λ‹ˆλ‹€.
  • LIMIT 1을 μ‚¬μš©ν•˜μ—¬ λΆˆν•„μš”ν•œ 데이터 쑰회λ₯Ό 쀄이고 μ„±λŠ₯을 μ΅œμ ν™”ν•©λ‹ˆλ‹€.

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

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

βœ…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λ₯Ό μ‘°νšŒν•  수 있음
  • 2. Backward Index Scan 적용됨
    • ➞ ORDER BY path DESC LIMIT 1을 톡해 μ—­μˆœ 탐색 μˆ˜ν–‰
  • 3. Using Index 적용됨
    • ➞ μΈλ±μŠ€μ—μ„œ 직접 데이터λ₯Ό κ°€μ Έμ˜€κΈ° λ•Œλ¬Έμ— μ„±λŠ₯ μ΅œμ ν™” κ°€λŠ₯

βœ…4️⃣ descendantsTopPathλ₯Ό ν™œμš©ν•œ μ •λ ¬ μ΅œμ ν™”

  • Path Enumeration λ°©μ‹μ—μ„œλŠ” μ •λ ¬ μƒνƒœλ₯Ό μœ μ§€ν•œ 채 descendantsTopPathλ₯Ό 검색할 수 μžˆμŠ΅λ‹ˆλ‹€.
    • path μ •λ ¬ μƒνƒœλ₯Ό μœ μ§€ν•˜λ©΄μ„œ μ—­μˆœμœΌλ‘œ 인덱슀λ₯Ό νƒμƒ‰ν•˜λ©΄, κ°€μž₯ 큰 path(descendantsTopPath)λ₯Ό λΉ λ₯΄κ²Œ 찾을 수 μžˆμŠ΅λ‹ˆλ‹€.
    • Backward Index Scan을 ν™œμš©ν•˜λ©΄ 둜그 μ‹œκ°„(log time) 내에 μ‘°νšŒκ°€ κ°€λŠ₯ν•©λ‹ˆλ‹€.

βœ…5️⃣ κ²°λ‘ 

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

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

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