2023. 11. 11. 19:32γDatabase/DB μ€ν°λ
μΌλ°μ μΈ μλ² - ν΄λΌμ΄μΈνΈ λͺ¨λΈμμ μλ² μΈ‘μ λ°μ΄ν°μ μμμ±μ μν΄ Databaseλ₯Ό νμ©νλ€.
μ΄λ¬ν μν©μμ λ°μ΄ν°μ νλ¦μ κ°λ΅νκ² νννλ©΄ ν΄λΌμ΄μΈνΈ - WAS - DB μ ννκ° λλλ°, μΌλ°μ μΈ RDB κΈ°μ€ λ°μ΄ν°λ€μ λͺ¨λ Diskμ μ μ¬λκΈ° λλ¬Έμ μμ€ν μ½μ μ λ°νκ² λκ³ μλ² νκ²½ λ΄ λ³λͺ©μ΄ κ°μ₯ λ§μ΄ λ°μνλ μ§μ μ€ νλκ° λλ€.
κ²°κ΅ WAS - DB κ° μλ΅ μλμ κ°μ μ΄ μ 체 μλ΅ μλμ κ°μ μΌλ‘ μ΄μ΄μ§λ κ²½μ°κ° λ§κΈ° λλ¬Έμ 쿼리μ κ°μ μ μ΄λ£¨μ΄λ΄λ κ²μ λͺΉμ μ€μνλ€.
μ¬κΈ°κΉμ§ μ€κ³ λλ©΄ κ°μ μ΄ μ€μνλ€λ κ²μ μ΄ν΄κ° λλλ°, 쿼리 μμ μ ν΅ν΄ κ°μ μ΄ μ΄λ£¨μ΄μ§κ³ μλμ§ νλ¨νλ κΈ°μ€μ 무μμΌλ‘ μΌμμΌν κΉ?
λ¬Όλ‘ ν΄λΌμ΄μΈνΈ μΈ‘μμ κ°λ°μ λꡬλ₯Ό ν΅ν΄ μλ΅ μλκ° μ΄λ»κ² λ³ννλμ§ νμΈν΄λ΄λ λκ³ , νΉμ μλ² μΈ‘μμ DBμ μλ΅ μκ°μ μ§μ μΈ‘μ ν΄λ΄λ λμ§λ§ μ¬κΈ°μμλ 그보λ€λ λ μ€μ μμ νμ©ν μ μλ μ€ν κ³νμ λν΄ κ°λ¨ν λ€λ£¨λ €κ³ νλ€.
λ€μ΄κ°κΈ° μμ
ν΄λΉ λ¬Έμμ μμλ€μ λͺ¨λ μλμ ν μ΄λΈ μν©μ κ°μ νκ³ μμ±
κ° ν μ΄λΈλ€μ λͺ¨λ λλ―Έ λ°μ΄ν°κ° ν¬ν¨
- Company
- idx: id
- rows: 200
- Item
- idx: id
- rows: 2000
- User
- idx: id
- rows: 10000
- Purchase
- idx: id
- rows: 500000
μ€ν κ³ν 쿼리 μμ±λ²
μ€ν κ³νμ νμΈμ ν¬κ² EXPLAIN λ¬Έκ³Ό EXPLAIN ANALYZE λ¬ΈμΌλ‘ λλλ€.
μ μμ κ²½μ°μ νΉμ 쿼리μ λν΄ DBκ° μμν κ²°κ³Όλ₯Ό μΆλ ₯νλ©°, νμλ μμκ³Ό λλΆμ΄ μ€μ 쿼리λ₯Ό μ€νμμΌ λ³Έ κ²°κ³ΌκΉμ§ μΆλ ₯νλ€.
ν΄λΉ λ¬Έμμμλ νμ(EXPLAIN ANALYZE) λ§μ λ€λ£¨κ² μ.
μ€νλ²
EXPLAIN (ANALYZE, VERBOSE, BUFFERS, TIMING) (
-- νμΈνκΈ° μν 쿼리
SELECT * FROM purchase WHERE count > 5;
)
κ²°κ³Ό
μ€ν κ³ν ν΄μ
μ½λ λ²
λ Έλμ κ°κ° μ΄λ€ λ΄μ©μ΄ λ€μ΄κ°λμ§ νμΈνκΈ° μμ, μ€ν κ³νμ μ½λ λ°©λ²μ μλμ κ°λ€.
- μ€ν κ³νμ κ° μμ μ λ Έλλ‘ ννν κ·Έλν ννλ‘ λνλλ©°, νΉμ λ Έλλ νμ λ Έλλ₯Ό ν¬ν¨ν μ μκ³ λ Έλ κ° λμ€λ νμ΄νλ‘ ννλλ€.
- κ°μ λμ€μ μμ κ°μλ μμμλΆν° μ€νλκ³ , λμ€κ° λ€λ₯Ό κ²½μ°μ λ κΉμ λ Έλμ μμ μ΄ λ¨Όμ μ€νλλ€.
- κ° λ Έλ νμμλ ν΄λΉ μμ μ λν μΆκ°μ μΈ μ€λͺ μ΄ ν¬ν¨λλ€. (μ μμ κΈ°μ€ Output, Filter λ±)
λ Έλ κ΅¬μ± μμ
μ€ν κ³νμ κ° λ Έλμλ μλμ μμλ€μ΄ ν¬ν¨λμ΄ μλ€.
- λΉμ©(Cost)
- λ°λ‘ λ¨μκ° μλ μΆμμ μΈ κ°μ΄μ§λ§, μΌλ°μ μΌλ‘ λ°μ΄ν°λ₯Ό κ°μ Έμ€λλ° νμν Disk I/Oμ λΉλμ κ·Έ μΈ μ¬μ©λλ μ»΄ν¨ν 리μμ€λ₯Ό μ’ ν©ν κ°
- μ»΄ν¨ν 리μμ€λ₯Ό μ΄μ μ μΌλ‘ ν¨μΆνκ³ μκΈ° λλ¬Έμ 쿼리 μ€ν μκ°κ³Ό μ λΉλ‘νμ§λ μμ§λ§, 쿼리 μ€νμμ Disk I/Oκ° μ°¨μ§νλ λΉμ€μ΄ ν¬λ€λ³΄λ μ΄λμ λμ κ²½ν₯μ±μ μ‘΄μ¬
- 2κ°μ κ°μ΄ λ°νλλ©°, νλλ 쑰건μ λ§λ 첫λ²μ§Έ rowλ₯Ό μ°Ύμ λκΉμ§ 걸리λ λΉμ©μ΄κ³ λ€λ₯Έ νλλ 쑰건μ λ§μ‘±νλ λͺ¨λ λ°μ΄ν°λ₯Ό μ°Ύμ λκΉμ§ 걸리λ λΉμ©
- λ‘μ°(Rows)
- νΉμ λ Έλμ κ²°κ³Όλ‘ λ°νλ λ°μ΄ν°(row)μ μ
- ν(width)
- νΉμ λ Έλμ κ²°κ³Όλ‘ λ°νλ λ°μ΄ν°μ νκ· width κ°(λ¨μ: λ°μ΄νΈ)
- λ²νΌ(Buffers)
- Buffers μ΅μ μ μΌ°μ λλ§ λνλλ κ°
- ν¬κ²λ hitκ³Ό readκ° μ‘΄μ¬νλλ°, hitμ λ²νΌ μΊμμμ μ½μ΄μ¨ λΈλ‘μ μμ΄κ³ readλ Disk IOλ₯Ό ν΅ν΄ μΌκ² μ¨ λΈλ‘μ μ(λΈλ‘ = μΌλ°μ μΌλ‘ 8kb, DBμ λͺ¨λ IOλ λΈλ‘ λ¨μλ‘ νν΄μ§)
- λ
Έλ νμ
- Seq Scan : ν μ΄λΈ Full Scan
- Index Scan : μΈλ±μ€λ₯Ό νμ©ν ν μ΄λΈ μ€μΊ
- Index Only Scan : 쿼리μμ μꡬλλ λͺ¨λ λ°μ΄ν°κ° μΈλ±μ€μ μ λΆ μ‘΄μ¬νμ¬ μΈλ±μ€λ§ μ€μΊ
- Nested Loop Join : ν μ΄λΈμ NL μ‘°μΈ νμμΌλ‘ ν΅ν©
- Hash Join : ν μ΄λΈμ ν΄μ μ‘°μΈ νμμΌλ‘ ν΅ν©
- Sort : ν μ΄λΈ μ λ ¬ μν
- Aggregate : μ§κ³ ν¨μλ₯Ό ν΅ν΄ λ°μ΄ν° ν΅ν©
λ€μν 쿼리 μμ
1. μΈλ±μ€ νν°λ§ μμ
쿼리
SELECT *
FROM item
WHERE id > 21800
ORDER BY id ASC
κ²°κ³Ό
ν΄μ
- item ν μ΄λΈμμ idκ° 21800λ³΄λ€ ν° λ°μ΄ν°λ§μ μ‘°ννκ³ μ΄λ₯Ό id μμΌλ‘ μ λ ¬νλ 쿼리
- idκ° μΈλ±μ€λ‘ μ€μ λμ΄ μκΈ° λλ¬Έμ Index Scanμ΄ μν. μ΄ λ κ²°κ³Ό rows μκ° 200 λΏμ΄κΈ° λλ¬Έμ Index Scanμ΄ μ€νλμλ€κ³ 보λ κ²μ΄ λ§κ³ μΈλ±μ€λ₯Ό ν΅ν΄ μ°Ύκ³ μνλ λ²μκ° λ λμ κ²½μ°μ λ¨μ ν μ΄λΈ νμ€μΊμΌλ‘ μνλ κ°λ₯μ±λ μ‘΄μ¬
- ORDER BY μ μ΄ μμμλ SORT λ Έλκ° λνλμ§ μμλλ°, μ΄λ μ΄λ―Έ μ λ ¬λ μΈλ±μ€λ₯Ό κΈ°μ€μΌλ‘ μ λ ¬μ μμ²νμκΈ° λλ¬Έμ μλ΅ κ°λ₯
2. μ‘°μΈ μμ
쿼리
SELECT *
FROM public.purchase p, public.user u
WHERE u.id = p.user_id AND u.avg_income > 80000000
κ²°κ³Ό
ν΄μ
- μ°κ° νκ· μλμ΄ 8000λ§μμ΄ λλ κ³ κ°μ λ°μ΄ν°μ ꡬ맀 λͺ©λ‘μ νμΈνλ 쿼리
- user ν μ΄λΈμμ μ°κ° νκ· μλ 쑰건μ λ§μ‘±νλ λ°μ΄ν°λ₯Ό ν μ΄λΈ νμ€μΊ λ°©μμ ν΅ν΄ νμΈ
- νν°λ§λ user λ°μ΄ν°λ₯Ό ν΅ν΄ μ‘°μΈ κΈ°μ€ μΉΌλΌμΈ user.id κ°μ ν€λ‘ κ°λ ν΄μν μ΄λΈ μμ±
- purchase ν μ΄λΈμμ user_id μΉΌλΌμ΄ ν΄μν μ΄λΈμ ν€ κ°μΌλ‘ μ‘΄μ¬νλ λ°μ΄ν°λ€μ νμ€μΊ νμμΌλ‘ νλ
- λλΌμ΄λΉ ν μ΄λΈμ νν°λ§λ κ²°κ³Όκ° λ μ μλ€λ©΄ NL μ‘°μΈμ μ ννμ κ°λ₯μ± UP
3. ν΅κ³ μμ
쿼리
SELECT u.id AS user_id, SUM(i.price * p.count) AS total_spent
FROM
public.purchase p,
public.item i,
(
SELECT id
FROM public.user
ORDER BY avg_income DESC
LIMIT 10
) u
WHERE u.id = p.user_id AND i.id = p.item_id AND p.created_at BETWEEN NOW() - interval '1 month' AND NOW()
GROUP BY u.id
κ²°κ³Ό
ν΄μ
- μ°κ° μμ μ΄ κ°μ₯ λμ μ΄λͺ μ μ μ μ μ§λ νλ¬ κ° μ¬μ© κΈμ‘ ν΅κ³
- user ν μ΄λΈμ νμ€μΊνμ¬ νμν λ°μ΄ν°λ₯Ό κ°μ Έμ¨ λ€ μ΄λ₯Ό ν΅ν΄ μλ μμΌλ‘ μμ 10κ°μ λ°μ΄ν°λ₯Ό μ»·ν νκ³ μ΄λ₯Ό μμ ν μ΄λΈ uλ‘ μ¬μ©
- uμ λ°μ΄ν°λ₯Ό νν΄ idλ₯Ό κΈ°μ€μΌλ‘ ν΄μ ν μ΄λΈ μμ±
- ν΄μ ν μ΄λΈμ μ΄μ©νμ¬ uμ purchase ν μ΄λΈ μ‘°μΈ
- item ν μ΄λΈ λ΄μμ μ΄μ μμ μ ν΅ν΄ μ‘°μΈλ ν μ΄λΈμ item_id κ°μ μ΄μ©ν μΈλ±μ€ μ€μΊ μμ μν
- νλ² ν΄μ μ‘°μΈμ μνν ν μ΄λΈκ³Ό item ν μ΄λΈμμ μΈλ±μ€ μ€μΊμ ν΅ν΄ νλν λ°μ΄ν° κ°μ NL μ‘°μΈ
- u.idλ₯Ό κΈ°μ€μΌλ‘ κ·Έλ£Ήν νκΈ° μν μν μν
- μν κ²°κ³Όλ₯Ό λ°νμΌλ‘ ν΅κ³ κ° μ΅μ’ μμ±
'Database > DB μ€ν°λ' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
ν μ΄λΈ μ€μΊ λ°©μμ λ°λ₯Έ DB Block IO μ λ΅ (Single vs Multi) (1) | 2023.12.02 |
---|---|
DB μΈλ±μ€ μμ±μ μ¬μ΄λ μ΄ννΈ(with Mysql) (1) | 2023.11.25 |
RDB vs NoSQL (0) | 2023.02.18 |
νΈλμμ 격리 μμ€ (0) | 2023.02.17 |
SQL Injection 곡격과 λμ (0) | 2023.02.11 |