βπ[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μ νμ©νμ¬ μ΅μ μ μ±λ₯μ 보μ₯νλ κ²μ΄ μ€μ.