๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

Java & Spring ์‹ค์ „ ๊ฐœ๋ฐœ

4ํŽธ. DB ์„ฑ๋Šฅ ๋ชจ๋‹ˆํ„ฐ๋ง ์ง‘์ค‘ ๋ถ„์„ + ์‹ค์ œ๋กœ ํšจ๊ณผ๊ฐ€ ์ปธ๋˜ SQL ํŠœ๋‹ ์‚ฌ๋ก€

๋ฐ˜์‘ํ˜•

 

DB ์„ฑ๋Šฅ ๋ชจ๋‹ˆํ„ฐ๋ง ์ง‘์ค‘ ๋ถ„์„

๐ŸŸฆ 4ํŽธ. DB ์„ฑ๋Šฅ ๋ชจ๋‹ˆํ„ฐ๋ง ์ง‘์ค‘ ๋ถ„์„ + ์‹ค์ œ๋กœ ํšจ๊ณผ๊ฐ€ ์ปธ๋˜ SQL ํŠœ๋‹ ์‚ฌ๋ก€

๋ฐฑ์—”๋“œ ์„œ๋น„์Šค๊ฐ€ ์ปค์งˆ์ˆ˜๋ก ๋ณ‘๋ชฉ์˜ ๋Œ€๋ถ€๋ถ„์€ ๊ฒฐ๊ตญ DB์—์„œ ๋ฐœ์ƒํ•œ๋‹ค.
Spring, JVM, ๋„คํŠธ์›Œํฌ ํŠœ๋‹๋„ ์ค‘์š”ํ•˜์ง€๋งŒ, ์šด์˜ ๊ฒฝํ—˜์ƒ ๊ฐ€์žฅ ์ฆ‰๊ฐ์ ์ด๊ณ  ๊ฐ€์žฅ ํฐ ์„ฑ๋Šฅ ๊ฐœ์„  ํšจ๊ณผ๋ฅผ ์ฃผ๋Š” ์ง€์ ์€ ๋ฐ”๋กœ DB ์„ฑ๋Šฅ ๋ชจ๋‹ˆํ„ฐ๋ง → SQL ํŠœ๋‹์ด๋‹ค.

์ด๋ฒˆ ํŽธ์—์„œ๋Š” ์‹ค์ œ ์šด์˜ ํ™˜๊ฒฝ์—์„œ ์‚ฌ์šฉํ•˜๋Š” DB ๋ชจ๋‹ˆํ„ฐ๋ง ๋ฐฉ์‹๊ณผ
์„ฑ๋Šฅ์„ ๋ช‡ ๋ฐฐ๊นŒ์ง€ ๋Œ์–ด์˜ฌ๋ฆฐ ์‹ค์ „ SQL ํŠœ๋‹ ์‚ฌ๋ก€๋ฅผ ์ •๋ฆฌํ•œ๋‹ค.


โ–  1) DB ์„ฑ๋Šฅ ๋ชจ๋‹ˆํ„ฐ๋ง์˜ ํ•ต์‹ฌ ๊ด€์ 

DB ์„ฑ๋Šฅ์€ ์•„๋ž˜ 4๊ฐ€์ง€ ์ง€ํ‘œ๋ฅผ ์ค‘์‹ฌ์œผ๋กœ ์ถ”์ ํ•˜๋ฉด ๋Œ€๋ถ€๋ถ„ ๋ฌธ์ œ๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ๋‹ค.


โœ” 1) ๋А๋ฆฐ ์ฟผ๋ฆฌ(Slow Query) ๋ชจ๋‹ˆํ„ฐ๋ง

์‹ค์ œ ์šด์˜์—์„œ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ์ง€ํ‘œ

  • ํ‰๊ท  ์ฟผ๋ฆฌ ์‘๋‹ต์‹œ๊ฐ„
  • 95/99 percentile
  • ์ดˆ๋‹น ์ฟผ๋ฆฌ ๊ฑด์ˆ˜(QPS)

MySQL ์˜ˆ:

  • slow query log ํ™œ์„ฑํ™”
  • pt-query-digest๋กœ ํŒจํ„ด ๋ถ„์„
  • AWS RDS → Performance Insights

Oracle/Sybase ์˜ˆ:

  • AWR / ASH / Statspack
  • sp_showplan / monitoring view
  • BI Matrix ํ˜น์€ ์ „์‚ฌ SQL ๋ชจ๋‹ˆํ„ฐ๋ง ๋„๊ตฌ

โœ” 2) ๋ฝ(Lock) & ๋ฝ ๊ฒฝํ•ฉ(Lock Contention)

DB ๊ณ ์งˆ์  ๋ณ‘๋ชฉ 1์ˆœ์œ„.

์ž์ฃผ ๋ณด๋Š” ์ง€ํ‘œ:

  • row lock, table lock
  • lock wait time
  • deadlock ๋ฐœ์ƒ ์—ฌ๋ถ€
  • ํŠน์ • ํŠธ๋žœ์žญ์…˜์˜ ๋Œ€๊ธฐ์—ด ๊ธธ์ด

ํŠนํžˆ ๊ธˆ์œต๊ถŒ์—์„œ๋Š” ๋ฝ ํ•˜๋‚˜ ๋•Œ๋ฌธ์— ์ „์ฒด ๋ฐฐ์น˜๊ฐ€ ๋ช‡ ์‹œ๊ฐ„ ์ง€์—ฐ๋˜๊ธฐ๋„ ํ•œ๋‹ค.


โœ” 3) ์ธ๋ฑ์Šค ์‚ฌ์šฉ ์—ฌ๋ถ€ & ํ’€์Šค์บ” ํƒ์ง€

์ธ๋ฑ์Šค๊ฐ€ ์žˆ์–ด๋„ ์กฐ๊ฑด์ด ์•„๋ž˜ ์ค‘ ํ•˜๋‚˜๋ฉด ์ธ๋ฑ์Šค๋ฅผ ๋ฌด์šฉ์ง€๋ฌผ๋กœ ๋งŒ๋“ ๋‹ค.

  • LIKE ‘%keyword’
  • ๊ณ„์‚ฐ์‹ ํฌํ•จ: WHERE DATE(created_at) = ...
  • ๋ฒ”์œ„ ์กฐ๊ฑด ๋‚จ๋ฐœ
  • OR ์กฐ๊ฑด ๋‹ค์ˆ˜
  • ์ธ๋ฑ์Šค ์ปฌ๋Ÿผ ๋ถˆ์ผ์น˜(์Šคํ‚ค๋งˆ-์ฟผ๋ฆฌ mismatch)

์‹ค์ œ ์šด์˜์—์„œ๋Š” ์‹คํ–‰๊ณ„ํš(EXPLAIN) ์˜ ๋ณ€ํ™”๋งŒ ๋ด๋„ ๋Œ€๋ถ€๋ถ„ ๋ฌธ์ œ๋ฅผ ์ฐพ๋Š”๋‹ค.


โœ” 4) ์„ธ์…˜/์ปค๋„ฅ์…˜ ๋ชจ๋‹ˆํ„ฐ๋ง

  • connection pool ์‚ฌ์ด์ฆˆ ๋ถ€์กฑ
  • idle session ๋ˆ„์ 
  • max_connections ์ดˆ๊ณผ
  • ์žฅ์‹œ๊ฐ„ ์‹คํ–‰๋˜๋Š” ์˜ค๋ž˜๋œ ์„ธ์…˜(=์ข€๋น„ ์„ธ์…˜)

Spring Boot์—์„œ HikariCP ๋กœ๊ทธ๋งŒ ๋ด๋„ ์ƒ๋‹น ๋ถ€๋ถ„ ํŒŒ์•…ํ•  ์ˆ˜ ์žˆ๋‹ค.


โ–  2) ์‹ค์ „ ํ™˜๊ฒฝ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋‹ˆํ„ฐ๋ง ๋„๊ตฌ

๐ŸŸฆ Spring ๊ธฐ๋ฐ˜ ์„œ๋น„์Šค ๋‚ด๋ถ€ ๋ชจ๋‹ˆํ„ฐ๋ง

  • Actuator + Micrometer
  • Prometheus + Grafana (์ฟผ๋ฆฌ ์ง€์—ฐ/connection pool ์ง€ํ‘œ ์‹œ๊ฐํ™”)
  • P6Spy, datasource proxy

๐ŸŸง DB ์ž์ฒด ๋ชจ๋‹ˆํ„ฐ๋ง

  • MySQL Performance Schema
  • Oracle AWR/ASH
  • Sybase monitor view
  • PostgreSQL pg_stat_statements

๐ŸŸฉ ๋กœ๊ทธ/์‹œ์Šคํ…œ ๋ ˆ๋ฒจ

  • CloudWatch / RDS Insights
  • ELK Stack
  • pin-point, ์Šค์นด์šฐํ„ฐ

์šด์˜์ด ์•ˆ์ •๋œ ํŒ€์ผ์ˆ˜๋ก ์œ„ ๋„๊ตฌ๋“ค์„ ๋™์‹œ์— ํ™œ์šฉํ•œ๋‹ค.


โ–  3) ์‹ค์ „์—์„œ ‘ํšจ๊ณผ๊ฐ€ ์—„์ฒญ ์ปธ๋˜’ SQL ํŠœ๋‹ ์‚ฌ๋ก€

์šด์˜ ํ™˜๊ฒฝ์—์„œ ์‹ค์ œ๋กœ ์„ฑ๋Šฅ์ด ํฌ๊ฒŒ ๊ฐœ์„ ๋˜์—ˆ๋˜ ๋Œ€ํ‘œ ์‚ฌ๋ก€๋“ค๋งŒ ์ •๋ฆฌํ–ˆ๋‹ค.


๐ŸŸฆ ์‚ฌ๋ก€ 1) OR → UNION ALL๋กœ ๋ณ€ํ™˜ (2000ms → 80ms)

๋ฌธ์ œ ์ฟผ๋ฆฌ:

SELECT * FROM orders
WHERE status = 'PAID'
   OR status = 'READY'
   OR status = 'COMPLETE';

๋ฌธ์ œ์ :

  • OR ์กฐ๊ฑด์ด ๋งŽ์•„์ง€๋ฉด ์ธ๋ฑ์Šค๋ฅผ ๋ชป ํƒ€๊ฑฐ๋‚˜ index merge๊ฐ€ ๋ฐœ์ƒ
  • leading column ํ•˜๋‚˜๊ฐ€ ์„ฑ๋Šฅ์„ ์ขŒ์šฐํ•˜๋Š”๋ฐ OR๊ฐ€ ์ด๋ฅผ ํŒŒ๊ดด

๊ฐœ์„ ์•ˆ:

SELECT * FROM orders WHERE status = 'PAID'
UNION ALL
SELECT * FROM orders WHERE status = 'READY'
UNION ALL
SELECT * FROM orders WHERE status = 'COMPLETE';

๊ฒฐ๊ณผ:

  • ์ธ๋ฑ์Šค๋ฅผ ์„ธ ๋ฒˆ ์ž˜ ํƒ€๋Š” ๊ฒƒ์œผ๋กœ ๋ถ„ํ• 
  • ์‘๋‹ต์‹œ๊ฐ„ 2000ms → 80ms (์•ฝ 25๋ฐฐ ๊ฐœ์„ )

๐ŸŸฆ ์‚ฌ๋ก€ 2) COUNT(*) ๋Œ€๋Ÿ‰ ์ง‘๊ณ„ → ์นด์šดํŠธ ์ „์šฉ ํ…Œ์ด๋ธ”๋กœ ๋ณ€๊ฒฝ (๋ฐฐ์น˜ 3์‹œ๊ฐ„ → 20๋ถ„)

๋ฌธ์ œ:

SELECT COUNT(*) FROM transaction_log WHERE created_at BETWEEN ? AND ?;

transaction_log๊ฐ€ ์ˆ˜์ฒœ๋งŒ ๊ฑด ์ด์ƒ์œผ๋กœ ์ฆ๊ฐ€ํ•˜๋ฉด์„œ ์ง‘๊ณ„ ๋ฐฐ์น˜๊ฐ€ ํญ๋ฐœ.

๊ฐœ์„ :

  • ๋งค์ผ 0์‹œ๋งˆ๋‹ค summary table์— count๋งŒ ์ €์žฅ
  • ์šด์˜ ์ฟผ๋ฆฌ๋Š” summary table์„ ์กฐํšŒ

๊ฒฐ๊ณผ:

  • ๋ฐฐ์น˜ 3์‹œ๊ฐ„ → 20๋ถ„
  • ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ CPU ์‚ฌ์šฉ๋Ÿ‰ 70% ๊ฐ์†Œ

๐ŸŸฆ ์‚ฌ๋ก€ 3) JOIN 4๋‹จ๊ณ„ → ์„œ๋ธŒ์ฟผ๋ฆฌ ์บ์‹ฑ + ์ธ๋ฑ์Šค ์ •๋ ฌ (800ms → 40ms)

๋ฌธ์ œ:

  • A → B → C → D ์กฐ์ธ์„ ํ†ตํ•ด ๋‹จ์ผ ์ƒํ’ˆ ์ •๋ณด๋ฅผ ์กฐํšŒ
  • C ํ…Œ์ด๋ธ”์—์„œ full scan ๋ฐœ์ƒ

์›์ธ:

  • C ํ…Œ์ด๋ธ”์˜ join key ์ปฌ๋Ÿผ์— ์ธ๋ฑ์Šค ์—†์—ˆ์Œ
  • order by ๋•Œ๋ฌธ์— filesort ๋ฐœ์ƒ

๊ฐœ์„ :

  • ํ•„์š”ํ•œ join key์— composite index ์ƒ์„ฑ
  • ์ •๋ ฌ ์กฐ๊ฑด์„ ์ธ๋ฑ์Šค ์ˆœ์„œ์™€ ์ผ์น˜ํ•˜๋„๋ก ๋ณ€๊ฒฝ
  • ์ผ๋ถ€ ์„œ๋ธŒ์ฟผ๋ฆฌ๋Š” Redis ์บ์‹ฑ

๊ฒฐ๊ณผ:

  • 800ms → 40ms (20๋ฐฐ ๋‹จ์ถ•)

๐ŸŸฆ ์‚ฌ๋ก€ 4) LIKE ‘%keyword’ → ์—ญ์ธ๋ฑ์Šค + ๊ฒ€์ƒ‰ ์ „์šฉ ํ…Œ์ด๋ธ” (1500ms → 50ms)

๋ฌธ์ œ:

WHERE name LIKE '%์€ํ–‰%'

๊ฐœ์„ :

  • ์—ญ์ธ๋ฑ์Šค or N-gram ์ธ๋ฑ์Šค ์ ์šฉ
  • ๊ฒ€์ƒ‰ ์ „์šฉ ํ…Œ์ด๋ธ” ์ƒ์„ฑ
  • ๋˜๋Š” ElasticSearch๋กœ ๋ถ„๋ฆฌ

๊ฒฐ๊ณผ:

  • 1500ms → 50ms
  • ๊ฒ€์ƒ‰ API 30๋ฐฐ ํ–ฅ์ƒ

๐ŸŸฆ ์‚ฌ๋ก€ 5) ๋ฌด๊ฑฐ์šด ์ •๋ ฌ ์ œ๊ฑฐ (order by → limit ์ตœ์ ํ™”) 1200ms → 60ms

๊ธฐ์กด:

SELECT * FROM account_history
WHERE user_id = ?
ORDER BY created_at DESC
LIMIT 20;

๋ฌธ์ œ:

  • created_at ์ธ๋ฑ์Šค๊ฐ€ ์—†์–ด ์ „์ฒด ์ •๋ ฌ ๋ฐœ์ƒ

๊ฐœ์„ :

CREATE INDEX idx_history_user_created_at ON account_history(user_id, created_at DESC);

๊ฒฐ๊ณผ:

  • ์ •๋ ฌ ๋น„์šฉ ์ œ๊ฑฐ
  • 1200ms → 60ms

โ–  4) Spring์—์„œ SQL ํŠœ๋‹ ํšจ๊ณผ๋ฅผ ์ตœ๋Œ€ํ™”ํ•˜๋Š” ๋ฐฉ์‹

โœ” 1) ๋ถˆํ•„์š”ํ•œ Lazy ๋กœ๋”ฉ ์ฐจ๋‹จ

@Query("select u from User u join fetch u.orders where u.id = :id")

โœ” 2) DTO projection ์ ๊ทน ์‚ฌ์šฉ

์—”ํ‹ฐํ‹ฐ ๊ธฐ๋ฐ˜๋ณด๋‹ค ์ „์†ก ๋น„์šฉ 30~80% ์ ˆ๊ฐ.

โœ” 3) ๋Œ€๋Ÿ‰ insert/update๋Š” batch ์˜ต์…˜ ํ•„์ˆ˜

HikariCP + Hibernate batch ์˜ต์…˜ ์กฐํ•ฉ ํšจ๊ณผ ํผ.

โœ” 4) ์ฝ๊ธฐ ์ „์šฉ ์ฟผ๋ฆฌ๋Š” replica๋กœ ๋ถ„๋ฆฌ

์ฝ๊ธฐ ๋ถ€ํ•˜๊ฐ€ ๋งŽ์€ ์„œ๋น„์Šค์—์„œ๋Š” ๋ฌด์กฐ๊ฑด ํ•ด์•ผ ํ•˜๋Š” ๊ตฌ์กฐ.


โ–  5) ๋งˆ๋ฌด๋ฆฌ

์ด๋ฒˆ ํŽธ์—์„œ๋Š” ์‹ค์ „ ํ™˜๊ฒฝ์—์„œ ๋ฐ”๋กœ ์“ฐ๋Š” DB ๋ชจ๋‹ˆํ„ฐ๋ง ์ง€ํ‘œ์™€ ๋„๊ตฌ,
๊ทธ๋ฆฌ๊ณ  ์‹ค์ œ ์šด์˜์—์„œ ํšจ๊ณผ๊ฐ€ ์ปธ๋˜ SQL ํŠœ๋‹ ์‚ฌ๋ก€๋“ค์„ ์†Œ๊ฐœํ–ˆ๋‹ค.

ํ•ต์‹ฌ์€ ํ•˜๋‚˜๋‹ค.

DB๋Š” “๊ฐ”์ด ์•„๋‹ˆ๋ผ “์ง€ํ‘œ + ์‹คํ–‰๊ณ„ํš + ํŒจํ„ด ๋ถ„์„”์œผ๋กœ ํŠœ๋‹ํ•ด์•ผ ํ•œ๋‹ค.

๋‹ค์Œ ํŽธ์—์„œ๋Š” ๋“œ๋””์–ด:

“์‹ค์ „ ์šด์˜ ์žฅ์•  ์‚ฌ๋ก€ 10์„  + ์žฅ์•  ๋ณต๊ตฌ ํ”Œ๋ ˆ์ด๋ถ”

์„ ๋‹ค๋ค„ ๋“œ๋ฆด๊ฒŒ์š”.

๋ฐ˜์‘ํ˜•