[DeepDive๐Ÿคฟ] SQL ์‹คํ–‰๊ณ„ํš์€ ๋ˆ„๊ฐ€ ์ •ํ• ๊นŒ? - DB ์˜ตํ‹ฐ๋งˆ์ด์ €

ํ•œ์œ ์ง„ยท2025๋…„ 12์›” 16์ผ

DeepDive

๋ชฉ๋ก ๋ณด๊ธฐ
4/4
post-thumbnail

DeepDive ์ฃผ์ œ

๐Ÿ’ก ์˜ตํ‹ฐ๋งˆ์ด์ €(Optimizer)์— ๋Œ€ํ•ด ์„œ์ˆ ํ•˜์‹œ์˜ค.

์ฃผ์ œ๋ฅผ ๋ณด๊ณ  ๋“  ์ƒ๊ฐ

  • ์˜ตํ‹ฐ๋งˆ์ด์ €? ์ตœ์ ํ™”? ์ฟผ๋ฆฌ ์ตœ์ ํ™” ๋งํ•˜๋Š”๊ฑด๊ฐ€?
  • ์ฟผ๋ฆฌ์กฐํšŒํ•˜๋Š” ์‹œ๊ฐ„์„ ์ค„์—ฌ์„œ ์„ฑ๋Šฅ๋†’์œผ๋ ค๊ณ  ์“ฐ๋Š”๊ฑฐ ์•„๋‹Œ๊ฐ€?
  • mysql, oracle ๋“ฑ DB์—”์ง„๋งˆ๋‹ค ๋‹ค๋ฅด๊ฒŒ ๋™์ž‘ํ•˜๋Š”๊ฑด๊ฐ€?

๐Ÿ‘‰ SQL ์ตœ์ ํ™” vs ์ฟผ๋ฆฌ ์ตœ์ ํ™” vs DB ์ตœ์ ํ™”

  • SQL ์ตœ์ ํ™” = ์ฟผ๋ฆฌ ์ตœ์ ํ™” โ†’ ์ด๋ฒˆ ๋”ฅ๋‹ค์ด๋ธŒ ์ฃผ์ œ
  • DB ์ตœ์ ํ™” โ†’ SQL ์ตœ์ ํ™”๋ฅผ ํฌํ•จํ•˜๋Š” ๋” ๋„’์€ ๊ฐœ๋…, DB์ „์ฒด์˜ ๊ตฌ์กฐ์  ์ตœ์ ํ™”(์Šคํ† ๋ฆฌ์ง€ ์—”์ง„/์บ์‹ฑ/๋ฒ„ํผ ํŠœ๋‹, ํŒŒํ‹ฐ์…”๋‹, ์ƒค๋”ฉ ๋“ฑ ๊ตฌ์กฐ์  ์ตœ์ ํ™”)

์˜ตํ‹ฐ๋งˆ์ด์ €(optimizer, ์ตœ์ ํ™”)๋ž€?

  • ์‚ฌ์šฉ์ž๊ฐ€ ์ž‘์„ฑํ•œ SQL ๋ฌธ์žฅ์„ ์‹ค์ œ๋กœ ์–ด๋–ป๊ฒŒ ์‹คํ–‰ํ• ์ง€๋ฅผ ๊ฒฐ์ •ํ•˜๋Š”ย ์‹คํ–‰ ๊ณ„ํš(Execution Plan)์„ ์ƒ์„ฑํ•˜๋Š” DBMS ๋‚ด๋ถ€ ๊ตฌ์„ฑ ์š”์†Œ
  • Why use?
    • ๊ฐ™์€ SQL์—๋„ ์‹คํ–‰ ๋ฐฉ๋ฒ•์ด ์—ฌ๋Ÿฌ๊ฐ€์ง€์ž„

    • ๋ฐ์ดํ„ฐ ์–‘/๋ถ„ํฌ์— ๋”ฐ๋ผ ํšจ์œจ์ ์ธ ๋ฐฉ๋ฒ•์ด ๋‹ฌ๋ผ์ง

    • ์œ„์— ๊ฒƒ์„ ๋‹ค ๊ณ ๋ คํ•˜์—ฌ SQL๋งˆ๋‹ค ์‚ฌ๋žŒ์ด ์‹คํ–‰๊ณ„ํš์„ ์ง์ ‘๊ณ ๋ฅด๊ธฐ๋Š” ๋ถˆ๊ฐ€๋Šฅ!

      โ‡’ ์ฆ‰, DBMS๊ฐ€ ์ž๋™์œผ๋กœ ์ตœ์ ์˜ ์‹คํ–‰ ๊ณ„ํš์„ ๊ณจ๋ผ ์ œ์ผ ํšจ์œจ์ด ์ข‹์€ ์‹คํ–‰๊ณ„ํš์„ ๊ณจ๋ผ์คŒ

์ฟผ๋ฆฌ ์‹คํ–‰ ์ ˆ์ฐจ

๐Ÿ’ก SQL Parsing > Optimization + Generation > Execution

image.png

  1. SQL Parsing
    • ์‚ฌ์šฉ์ž๋กœ๋ถ€ํ„ฐ ์š”์ฒญ๋œ SQL๋ฌธ์žฅ์„ ์ชผ๊ฐœ์„œ ๊ตฌ์„ฑ์š”์†Œ๋ฅผ ํŒŒ์•…ํ•˜๊ณ  ์ด๋ฅผ ๋ถ„๋ฆฌํ•˜์—ฌ ํŒŒ์Šค ํŠธ๋ฆฌ๋ฅผ ๋งŒ๋“ฌ
    • SQL๋ฌธ์žฅ์ด ๋ฌธ๋ฒ•์ ์œผ๋กœ ์ž˜๋ชป๋๋‹ค๋ฉด ์ด ๋‹จ๊ณ„์—์„œ ๊ฑธ๋Ÿฌ์ง
  2. Optimization + Generation (์ตœ์ ํ™” ๋ฐ ์‹คํ–‰ ๊ณ„ํš ์ˆ˜๋ฆฝ)
    • ํŒŒ์ŠคํŠธ๋ฆฌ ์ฐธ์กฐํ•˜๋ฉด์„œ ์กฐ์ธ์ˆœ์„œ, ์ธ๋ฑ์Šค ์‚ฌ์šฉ ์œ ๋ฌด ๋“ฑ ๋‹ค์–‘ํ•œ ์กฐํ•ฉ์„ ๊ณ ๋ คํ•˜๋ฉฐ ์‹คํ–‰๊ณ„ํš ์„ธ์šฐ๊ณ  ์—”์ง„์ด ์‹ค์ œ๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ์ฝ”๋“œ๋‚˜ ํ”„๋กœ์‹œ์ € ํ˜•ํƒœ๋กœ ํฌ๋งทํŒ…
  3. Execution
    • 2๋ฒˆ์—์„œ ๊ฒฐ์ •๋œ ์‹คํ–‰๊ณ„ํš(ํ…Œ์ด๋ธ”์˜ ์ฝ๊ธฐ ์ˆœ์„œ, ์„ ํƒ๋œ ์ธ๋ฑ์Šค ๋“ฑ)๋Œ€๋กœ ์Šคํ† ๋ฆฌ์ง€ ์—”์ง„์— ๋ ˆ์ฝ”๋“œ๋ฅผ ์ฝ์–ด์˜ค๊ณ  ์‹คํ–‰ํ•˜์—ฌ ์‚ฌ์šฉ์ž์—๊ฒŒ ๊ฒฐ๊ณผ๊ฐ’ ๋ฐ˜ํ™˜

์˜ตํ‹ฐ๋งˆ์ด์ €์˜ ์ข…๋ฅ˜

  1. ๊ทœ์น™ ๊ธฐ๋ฐ˜ ์ตœ์ ํ™”(RBO : Rule-Based Optimizer) โ† ์˜ˆ์ „ ์ดˆ๊ธฐ ๋ฒ„์ „์˜ ์˜ค๋ผํด์—์„œ ์‚ฌ์šฉ
    • ์˜ตํ‹ฐ๋งˆ์ด์ €์— ์ด๋ฏธ ๋‚ด์žฅ๋œ ์šฐ์„ ์ˆœ์œ„์— ๋”ฐ๋ผ ์‹คํ–‰๊ณ„ํš์„ ์ˆ˜๋ฆฝํ•˜๋Š” ๋ฐฉ์‹
    • ํ†ต๊ณ„์ •๋ณด(ํ…Œ์ด๋ธ” ๋ ˆ์ฝ”๋“œ ๊ฑด์ˆ˜, ์ปฌ๋Ÿผ๊ฐ’์˜ ๋ถ„ํฌ๋„ ๋“ฑ)์„ ์กฐ์‚ฌ X โ†’ ๊ฐ™์€ ์ฟผ๋ฆฌ์— ๊ฑฐ์˜๊ฐ™์€ ์‹คํ–‰๋ฐฉ๋ฒ• ๋งŒ๋“ค์–ด๋ƒ„ โ†’ But, ์‚ฌ์šฉ์ž์˜ ๋ฐ์ดํ„ฐ ๋ถ„ํฌ๋„๋Š” ๋งค์šฐ ๋‹ค์–‘ํ•˜๊ธฐ์— ์ด๋ฏธ ์˜ค๋ž˜์ „๋ถ€ํ„ฐ ์‚ฌ์šฉX
    • ์ผ๋ฐ˜์ ์œผ๋กœ ๊ณ ์ •๋œ RBO์˜ ์šฐ์„ ์ˆœ์œ„
      image.png
  2. ๋น„์šฉ ๊ธฐ๋ฐ˜ ์ตœ์ ํ™”(CBO : Cost-Based Optimizer) โ† ํ˜„์žฌ ๋Œ€๋ถ€๋ถ„์˜ RDBMS๊ฐ€ ์‚ฌ์šฉ
    • ์ฟผ๋ฆฌ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ์—ฌ๋Ÿฌ๊ฐ€์ง€ ๋ฐฉ๋ฒ•๋“ค์˜ ๊ฐ ๋‹จ์œ„ ์ž‘์—… ๋น„์šฉ(๋ถ€ํ•˜) ์ •๋ณด์™€ ๋Œ€์ƒ ํ…Œ์ด๋ธ”์˜ ์˜ˆ์ธก๋œ ํ†ต๊ณ„์ •๋ณด๋ฅผ ์ด์šฉํ•ด ์‹คํ–‰ ๊ณ„ํš๋ณ„ ๋น„์šฉ์„ ์‚ฐ์ถœํ•˜์—ฌ ๋น„์šฉ์ด ์ตœ์†Œ์ธ ๋ฐฉ์‹์„ ์„ ํƒํ•ด์—ฌ ์‹คํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•

๐Ÿค” ๊ฒฐ๊ตญ ์˜ตํ‹ฐ๋งˆ์ด์ €๋Š” DBMS ๋‚ด๋ถ€ ์—”์ง„์œผ๋กœ ๋‚ด๊ฐ€ ๊ฑด๋“ค ์ˆ˜ ์—†๋Š”๋ฐ ์™œ ์•Œ์•„์•ผํ• ๊นŒ?

  • ์˜ตํ‹ฐ๋งˆ์ด์ €๊ฐ€ ์‹คํ–‰๊ณ„ํš์„ ์ž๋™์œผ๋กœ ๊ณ ๋ฅด์ง€๋งŒ ํ•ญ์ƒ ์ตœ์„ ์€ ์•„๋‹˜! โ†’ ๊ทธ ์‹คํ–‰๊ณ„ํš์„ ์šฐ๋ฆฌ๊ฐ€ ์ฝ์„ ์ค„ ์•Œ์•„์•ผ ์ƒํ™ฉ์— ๋งž๋Š” ์ฟผ๋ฆฌ๋กœ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐ ํ•  ์ˆ˜ ์žˆ์Œ โ‡’ ์ฆ‰, ์ฟผ๋ฆฌ๋ฅผ ์–ด๋–ป๊ฒŒ ์งœ๋А๋ƒ, ์ธ๋ฑ์Šค๋ฅผ ์–ด๋–ป๊ฒŒ ๋‘๋А๋ƒ์— ๋”ฐ๋ผ ์˜ตํ‹ฐ๋งˆ์ด์ €์˜ ์„ ํƒ์ด ๋‹ฌ๋ผ์ง(์„ฑ๋Šฅ์ด ๋‹ฌ๋ผ์ง)
  • ex) Like ์‚ฌ์šฉ์‹œ ์ธ๋ฑ์Šค ํƒˆ๋•Œ์™€ ์•ˆํƒˆ๋•Œ
SELECT * FROM member WHERE name LIKE '%์œ ์ง„';
// -> %๊ฐ€ ์•ž์— ์žˆ์œผ๋ฉด ์ธ๋ฑ์Šค๋ฅผ ์“ธ ์ˆ˜ ์—†์Œ โ†’ ํ’€์Šค์บ”ํ•ด์•ผํ•จ
// -> B-Tree์ธ๋ฑ์Šค๋Š” ์•ž๋ถ€๋ถ„๋ถ€ํ„ฐ ๋น„๊ต๊ฒ€์ƒ‰ํ•˜๋‹ˆ๊นŒ
SELECT * FROM member WHERE name LIKE 'ํ•œ%';
// -> %๊ฐ€ ๋’ค์— ์žˆ์œผ๋ฉด ์˜ตํ‹ฐ๋งˆ์ด์ €๊ฐ€ ์ธ๋ฑ์Šค๋ฅผ ํ™œ์šฉ ๊ฐ€๋Šฅ.

๊ธฐ๋ณธ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ

  • DB๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ๊ธฐ๋ณธ์ ์œผ๋กœ ์–ด๋–ป๊ฒŒ ์ฝ๊ณ , ์กฐ์ธํ•˜๊ณ , ์ •๋ ฌํ• ๊นŒ?

1. ํ’€ ํ…Œ์ด๋ธ” ์Šค์บ” vs ํ’€ ์ธ๋ฑ์Šค ์Šค์บ”

  • ํ’€ ํ…Œ์ด๋ธ” ์Šค์บ” : ํ…Œ์ด๋ธ”์˜ ๋ชจ๋“  ๋ ˆ์ฝ”๋“œ๋ฅผ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋๊นŒ์ง€ ์ฝ์Œ
    • ํ…Œ์ด๋ธ”์˜ ๋ ˆ์ฝ”๋“œ ๊ฑด์ˆ˜ ์ž‘์„๋•Œ
    • Where์ ˆ์ด๋‚˜ On์— ์ธ๋ฑ์Šค๋ฅผ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ ์ ˆํ•œ ์กฐ๊ฑด์ด ์—†๋Š” ๊ฒฝ์šฐ
    • ex ) SELECT * FROM member;
  • ํ’€ ์ธ๋ฑ์Šค ์Šค์บ” : ํ…Œ์ด๋ธ”์„ ์ง์ ‘ ์ฝ์ง€ ์•Š๊ณ , ์ธ๋ฑ์Šค๋งŒ ๋๊นŒ์ง€ ์ฝ์Œ
    • SELECT ์ปฌ๋Ÿผ์ด ์ „๋ถ€ ์ธ๋ฑ์Šค์— ํฌํ•จ๋  ๋•Œ(covering index) ์œ ๋ฆฌ.
    • ex ) SELECT count(*) FROM member;
      • ๋‹จ์ˆœํžˆ ๊ฐœ์ˆ˜๋งŒ ์„ธ๋Š”๊ฒƒ์ด๋ผ ํ’€ํ…Œ์ด๋ธ”๋ณด๋‹ค๋Š” ์šฉ๋Ÿ‰์ด ์ž‘์€ ํ’€ ์ธ๋ฑ์Šค ์Šค์บ”์„ ์„ ํƒํ•  ํ™•๋ฃ”์ด ๋†’์Œ
  • ๋ฆฌ๋“œ ์–ดํ—ค๋“œ : ํ’€ ์Šค์บ”์„ ํ•  ๊ฒฝ์šฐ ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์Šค๋ ˆ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํšจ๊ณผ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•
    • ํ’€ ์Šค์บ”ํ• ๋•Œ ์ˆœ์„œ๋Œ€๋กœ ํ•˜๋‚˜์”ฉ ์ฝ์–ด๋“œ๋ฆฌ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, ๋ฏธ๋ฆฌ ์ฝ์–ด์„œ ๋ฒ„ํผํ’€์— ๊ฐ€์ ธ๋‹ค ๋‘๋Š”๊ฒƒ.
    • InnoDB ์Šคํ† ๋ฆฌ์—”์ง„์—์„œ ์‚ฌ์šฉ
    • ์—ฌ๊ธฐ์„œ ๋งํ•˜๋Š” ํ’€์Šค์บ” = ํ’€ ํ…Œ์ด๋ธ”, ํ’€์ธ๋ฑ์Šค ๋ชจ๋‘๋ฅผ ์ผ์ปซ๋Š”๋ง

๐Ÿ’ก ์„œ๋น„์Šค ์„ค๊ณ„ ๊ด€์ 

  • โ€œ์†Œ๊ทœ๋ชจ ํ…Œ์ด๋ธ”โ€ โ†’ ํ’€์Šค์บ” ๊ดœ์ฐฎ์Œ
  • โ€œ์ž์ฃผ ๊ฒ€์ƒ‰/์ •๋ ฌ๋˜๋Š” ์ปฌ๋Ÿผโ€ โ†’ ์ธ๋ฑ์Šค ์ฃผ๊ธฐ

2. ๋ณ‘๋ ฌ์ฒ˜๋ฆฌ

  • ํ•˜๋‚˜์˜ ์ฟผ๋ฆฌ๋ฅผ ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๋‚˜๋ˆ„์–ด ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ
  • ์•„๋ฌด๋Ÿฐ ์กฐ๊ฑด ์—†์ด ๋‹จ์ˆœํžˆ ํ…Œ์ด๋ธ”์˜ ์ „์ฒด ๊ฑด์ˆ˜๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ์ฟผ๋ฆฌ๋งŒ ๋ณ‘๋ ฌ๋กœ ์ฒ˜๋ฆฌ๊ฐ€๋Šฅ
  • ์Šค๋ ˆ๋“œ ๊ฐœ์ˆ˜๊ฐ€ ๋งŽ์„์ˆ˜๋ก ์ฟผ๋ฆฌ์ฒ˜๋ฆฌ์‹œ๊ฐ„์€ ์ค„๊ฒ ์ง€๋งŒ, CPU์ฝ”์–ด ๊ฐœ์ˆ˜๋ฅผ ๋„˜์–ด์„œ๋Š” ๊ฒฝ์šฐ์—๋Š” ์˜คํžˆ๋ ค ์„ฑ๋Šฅ์ €ํ•˜
  • ex) SET SESSION innodb_parallel_read_threads=2;

๐Ÿ’ก์„œ๋น„์Šค ์„ค๊ณ„ ๊ด€์ 

  • ๋ณดํ†ต MySQL ๋‹จ๋…๋ณด๋‹จ DW/OLAP(๋ถ„์„์šฉ) DB์—์„œ ํ™œ์šฉ ๊ฐ€์น˜ โ†‘
  • ์ผ๋ฐ˜ ์›น์„œ๋น„์Šค ํŠธ๋žœ์žญ์…˜์„ฑ ์ฟผ๋ฆฌ์—์„œ๋Š” ๊ฑฐ์˜ ์‹ ๊ฒฝ ์•ˆ ์จ๋„ ๋จ.

3. ORDER BY ์ฒ˜๋ฆฌ

  1. ์ธ๋ฑ์Šค ์ด์šฉ
    • ์žฅ์  : ์ด๋ฏธ ์ •๋ ฌ๋œ ์ธ๋ฑ์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋งค์šฐ ๋น ๋ฆ„
    • ex) SELECT * FROM members ORDER BY age;
      • age๊ฐ€ ์ด๋ฏธ ์ธ๋ฑ์Šค๋กœ ์ง€์ •๋˜์–ด์žˆ๋‹ค๋ฉด, ์˜ตํ‹ฐ๋งˆ์ด์ €๋Š” ๊ทธ๋ƒฅ ์ธ๋ฑ์Šค ์ˆœ์„œ๋Œ€๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์–ด์˜ค๊ธฐ๋งŒ ํ•˜๋ฉด๋จ(๋ณ„๋„์˜ ์ •๋ ฌ ์—ฐ์‚ฐ ํ•˜์ง€X)
    • ๋‹จ์  : ์“ฐ๊ธฐ ์ž‘์—…์‹œ ์ธ๋ฑ์Šค ์ถ”๊ฐ€/์‚ญ์ œ ์ž‘์—…์ด ํ•„์š”ํ•ด์„œ ๋А๋ฆผ, ์ธ๋ฑ์Šคโ†‘โ†’๋ฉ”๋ชจ๋ฆฌโ†‘
  2. Filesort์ด์šฉ
    • ๊ณผ์ • : ์กฐ๊ฑด์— ๋งž๋Š” ํ…Œ์ด๋ธ” ๊ฐ€์ ธ์˜ด โ†’ ๊ฒฐ๊ณผ๋ฅผ ์ž„์‹œ tb/๋ฉ”๋ชจ๋ฆฌ(์†ŒํŠธ๋ฒ„ํผ)์— ๋‹ด์Œ โ†’ ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ๋‹ค์‹œ ์ •๋ ฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋Œ๋ฆผโ†’ ์ •๋ ฌ๋œ ๊ฒฐ๊ณผ ๋ฐ˜ํ™˜
    • ์ธ๋ฑ์Šค๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ - ์ •๋ ฌ๊ธฐ์ค€โ†‘, group by / distinct ์‚ฌ์šฉํ• ๊ฒฝ์šฐ ๋“ฑ
    • ์žฅ์  : ์ธ๋ฑ์Šค๋ฅผ ์ด์šฉํ• ๋•Œ์˜ ๋‹จ์ ์ด ์—†์–ด์ง.
    • ๋‹จ์  : ์ •๋ ฌ ์ž‘์—…์ด ์ฟผ๋ฆฌ ์‹คํ–‰ ์‹œ ์ฒ˜๋ฆฌ๋˜๋ฏ€๋กœ ๋ ˆ์ฝ”๋“œ ๊ฑด์ˆ˜๊ฐ€ ๋งŽ์•„์งˆ์ˆ˜๋ก ์ฟผ๋ฆฌ์˜ ์‘๋‹ต ์†๋„๊ฐ€ ๋А๋ฆผ,๋””์Šคํฌ I/O ๋ฐœ์ƒ ๊ฐ€๋Šฅ
    • ์†ŒํŠธ๋ฒ„ํผ : ์ •๋ ฌ์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•œ ๋ณ„๋„์˜ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„, ์‹คํ–‰์™„๋ฃŒ ํ›„ ๋ฐ”๋กœ ๋ฐ˜๋‚ฉ
      • ์ •๋ ฌํ•ด์•ผํ•˜๋Š” ๋ ˆ์ฝ”๋“œ ํฌ๊ธฐ์— ๋”ฐ๋ผ ๊ฐ€๋ณ€์ ์œผ๋กœ ์ฆ๊ฐ€, ์ตœ๋Œ€ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋ฒ„ํผ๊ณต๊ฐ„ ์ง€์ • ๊ฐ€๋Šฅ
      • ์ •๋ ฌ์— ํ•„์š”ํ•œ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ์ตœ๋Œ€์น˜๋ณด๋‹ค ํฐ๊ฒฝ์šฐ ๋ ˆ์ฝ”๋“œ๋ฅผ ์—ฌ๋Ÿฌ์กฐ๊ฐ์œผ๋กœ ๋‚˜๋ˆ  ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ๋””์Šคํฌ ์‚ฌ์šฉโ†’ ๋””์Šคํฌ I/O โ†‘ โ†’ ๊ทธ๋ ‡๋‹ค๊ณ  ์†ŒํŠธ๋ฒ„ํผ๋ฅผ ํฌ๊ฒŒ ์„ค์ •ํ•ด๋„ ์„ฑ๋Šฅ์€ ๋น„์Šทํ•จ
    • ์ •๋ ฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜
      1. ์‹ฑ๊ธ€ ํŒจ์Šค(Single-pass) : ๋ ˆ์ฝ”๋“œ ์ „์ฒด๋ฅผ ์†ŒํŠธ ๋ฒ„ํผ์— ๋‹ด๋Š” ์ •๋ ฌ ๋ฐฉ์‹ โ†’ MySQL ์ตœ์‹ ๋ฒ„์ „์—์„œ ์‚ฌ์šฉ
        • ์ •๋ ฌ๊ธฐ์ค€ ์ปฌ๋Ÿผ, Select์˜ ์ปฌ๋Ÿผ ์ „๋ถ€ ๋‹ด์Œ
      2. ํˆฌ ํŒจ์Šค(Two-pass) : ์ •๋ ฌ ๊ธฐ์ค€ ์ปฌ๋Ÿผ๊ณผ PK๋งŒ ์†ŒํŠธ ๋ฒ„ํผ์— ๋‹ด๋Š” ์ •๋ ฌ ๋ฐฉ์‹
        • ์†ŒํŠธ ๋ฒ„ํผ์— ๋‹ด์€๊ฑธ ์ˆœ์„œ๋Œ€๋กœ ๋‹ค์‹œ PK๋กœ ํ…Œ์ด๋ธ”์„ ์ฝ์–ด selectํ•  ์ปฌ๋Ÿผ ๊ฐ€์ ธ์˜ด โ†’ ์ฆ‰, ํ…Œ์ด๋ธ” 2๋ฒˆ ์ฝ์–ด์—ฌํ•จ โ‡’ MySQL ์ตœ์‹ ๋ฒ„์ „์—์„œ๋Š” ์ฃผ๋กœ ์‹ฑ๊ธ€ ํŒจ์Šค ์‚ฌ์šฉ(ํˆฌํŒจ์Šค ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๋„ ์กด์žฌํ•จ)
  • ์ •๋ ฌ ์ฒ˜๋ฆฌ๋ฐฉ๋ฒ•
    • ์ธ๋ฑ์Šค๋ฅผ ์ด์šฉํ•œ ์ •๋ ฌ โ†’ ์กฐ์ธ์—์„œ ๋“œ๋ผ์ด๋น™ ํ…Œ์ด๋ธ”๋งŒ ์ •๋ ฌ โ†’ ์กฐ์ธ์—์„œ ์กฐ์ธ ๊ฒฐ๊ณผ๋ฅผ ์ž„์‹œ ํ…Œ์ด๋ธ”๋กœ ์ €์žฅ ํ›„ ์ •๋ ฌ
    • ๋“œ๋ผ์ด๋น™ ํ…Œ์ด๋ธ” : ์กฐ์ธ์„ ์‹คํ–‰ํ•˜๊ธฐ ์ „์— ์ฒซ๋ฒˆ์งธ๋กœ ์ฝํžˆ๋Š” ํ…Œ์ด๋ธ”

๐Ÿ’ก ์„œ๋น„์Šค ์„ค๊ณ„ ๊ด€์ 

  • โ€œ์ด ์ปฌ๋Ÿผ์œผ๋กœ ์ •๋ ฌ ์ž์ฃผ ํ•œ๋‹คโ€ โ†’ ํ•ด๋‹น ์ปฌ๋Ÿผ์— ์ธ๋ฑ์Šค ๊ฑธ๋ฉด โ†’ ์˜ตํ‹ฐ๋งˆ์ด์ €๊ฐ€ ์ธ๋ฑ์Šค ์ •๋ ฌ ์‚ฌ์šฉ
  • โ€œ์ •๋ ฌ ์ผ€์ด์Šค๊ฐ€ ๋‹ค์–‘ํ•˜๋‹คโ€ โ†’ ๋ชจ๋“  ๊ฒฝ์šฐ๋ฅผ ์ธ๋ฑ์Šค๋กœ ์ปค๋ฒ„ ๋ถˆ๊ฐ€ โ†’ ์˜ตํ‹ฐ๋งˆ์ด์ €๋Š” ํŒŒ์ผ์†ŒํŠธ ์„ ํƒ

4. GRUOP BY ์ฒ˜๋ฆฌ

  1. ์ธ๋ฑ์Šค ์Šค์บ”์„ ์ด์šฉํ•˜๋Š” GROUP BY
    • ์กฐ์ธ์˜ ๋“œ๋ผ์ด๋น™ ํ…Œ์ด๋ธ”์— ์ธ๋ฑ์Šค๊ฐ€ ์žˆ๊ณ , ํ•ด๋‹น ์ธ๋ฑ์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ทธ๋ฃจํ•‘์„ ํ•˜๋Š” ๊ฒฝ์šฐ, ์ธ๋ฑ์Šค๋ฅผ ์ˆœ์„œ๋Œ€๋กœ ์ฝ์œผ๋ฉด์„œ ๊ทธ๋ฃจํ•‘ ์ž‘์—…์„ ์ˆ˜ํ–‰, ๊ทธ ๊ฒฐ๊ณผ๋กœ ์กฐ์ธ์„ ์ฒ˜๋ฆฌ
  2. ๋ฃจ์Šค ์ธ๋ฑ์Šค ์Šค์บ”์„ ์ด์šฉํ•˜๋Š” GROUP BY
    • ์ธ๋ฑ์Šค์˜ ๋ ˆ์ฝ”๋“œ๋ฅผ ๊ฑด๋„ˆ๋›ฐ๋ฉด์„œ ํ•„์š”ํ•œ ๋ถ€๋ถ„๋งŒ ์ฝ์–ด์„œ ๊ฐ€์ ธ์˜ค๋Š” ๋ฐฉ์‹
    • ex) SELECT a, MAX(b) FROM t GROUP BY a
      • ์ธ๋ฑ์Šค (a, b)๊ฐ€ ์žˆ์„ ๋•Œ, ๊ฐ a ๊ทธ๋ฃน์—์„œ b์˜ ์ตœ์†Œ/์ตœ๋Œ€๊ฐ€ ๋˜๋Š” ๊ฒฝ๊ณ„๊ฐ’๋งŒ ์ฐ๊ณ  ๊ฑด๋„ˆ๋œ€
  3. ์ž„์‹œ ํ…Œ์ด๋ธ”์„ ์‚ฌ์šฉํ•˜๋Š” GROUP BY
    • ์ธ๋ฑ์Šค๋ฅผ ์ „ํ˜€ ์‚ฌ์šฉํ•˜์ง€ ๋ชปํ•˜๋Š” ๊ฒฝ์šฐ ์ž„์‹œ ํ…Œ์ด๋ธ” ์‚ฌ์šฉ

๐Ÿ’ก ์„œ๋น„์Šค ์„ค๊ณ„ ๊ด€์ 

  • ์ž์ฃผ ์“ฐ๋Š” GROUP BY ํŒจํ„ด์ด ๊ณ ์ •์  ? โ†’ ์ธ๋ฑ์Šค ์Šค์บ”์„ ์ด์šฉํ•˜๋Š” GROUP BY
  • ๊ทธ๋ฃน๋ณ„ ๋Œ€ํ‘œ๊ฐ’(์ตœ์‹ /์ตœ์†Œ/์ตœ๋Œ€/Distinct)์ด ํ•ต์‹ฌ? โ†’ ๋ฃจ์Šค ์ธ๋ฑ์Šค ์Šค์บ”์„ ์ด์šฉํ•˜๋Š” GROUP BY

์˜ตํ‹ฐ๋งˆ์ด์ €์˜ ์‹คํ–‰ ๊ณ„ํš ํ™•์ธ ๋ฐฉ๋ฒ•

image.png

  • type: ALL โ†’ ํ’€์Šค์บ” / type: ref โ†’ ์ธ๋ฑ์Šค ์Šค์บ”
  • Extra๊ฐ€ Using filesort โ†’ ํŒŒ์ผ์†ŒํŒ… ์‚ฌ์šฉ / Using index โ†’ ์ธ๋ฑ์Šค ์‚ฌ์šฉ

์˜ตํ‹ฐ๋งˆ์ด์ €๋Š” RDBMS, NoSQL ๋‹ค ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ๊ฑด๊ฐ€?

๐Ÿ’ก ๋‘˜๋‹ค ์‚ฌ์šฉ๊ฐ€๋Šฅํ•˜์ง€๋งŒ, RDBMS๊ฐ€ ๋” ๋งŽ์ด ๋ฐœ์ „๋จ.
NoSQL์€ ๋ณต์žกํ•œ ์ฟผ๋ฆฌ ์–ธ์–ด๊ฐ€ ์—†๊ฑฐ๋‚˜ ๋‹จ์ˆœ โ†’ ์ธ๋ฑ์Šค ์„ ํƒ, ์ƒค๋”ฉ ํ‚ค ์„ ํƒ ์ •๋„์˜ ๊ฐ„๋‹จํ•œ ์˜ตํ‹ฐ๋งˆ์ด์ €๋Š” ์กด์žฌํ•จ
์œ„์— ์„ค๋ช…ํ•œ ๊ฒƒ๋“ค์€ RDBMS ๊ธฐ์ค€!

๐Ÿ“Œ ๋งˆ๋ฌด๋ฆฌ

์˜ตํ‹ฐ๋งˆ์ด์ €๋ž€, ์‚ฌ์šฉ์ž๊ฐ€ ๋ณด๋‚ด๋Š” SQL์„ ์–ด๋–ป๊ฒŒ ํ•˜๋ฉด ๋น„์šฉ์ด ์ ๊ณ , ๋น ๋ฅด๊ฒŒ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š”์ง€๋ฅผ ๊ณ„ํšํ•˜๋Š” ์—”์ง„์œผ๋กœ, ์˜ตํ‹ฐ๋งˆ์ด์ €์˜ ๋™์ž‘ ์›๋ฆฌ๋ฅผ ์•Œ์•„์•ผ โ€œ๋‚ด ์ฟผ๋ฆฌ๊ฐ€ ์™œ ๋А๋ฆฐ์ง€โ€ ์›์ธ์„ ์ฐพ๊ณ , ์–ด๋–ป๊ฒŒ ๊ณ ์น ์ง€(์ฟผ๋ฆฌ ์ˆ˜์ •/์ธ๋ฑ์Šค ์ถ”๊ฐ€/์บ์‹ฑ) ํŒ๋‹จํ•  ์ˆ˜ ์žˆ๋‹ค!

๐Ÿ“ ํšŒ๊ณ 

์ด๋ฒˆ ์ •๋ฆฌ๋ฅผ ํ†ตํ•ด โ€œSQL์ด ์‹คํ–‰๋˜๊ธฐ๊นŒ์ง€ DB ๋‚ด๋ถ€์—์„œ ์–ด๋–ค ์ผ์ด ๋ฒŒ์–ด์ง€๋Š”์ง€โ€๋ฅผ ๊ตฌ์กฐ์ ์œผ๋กœ ์ดํ•ดํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค.
ํŠนํžˆ ๊ฐ™์€ SQL์ด๋ผ๋„ ์‹คํ–‰๊ณ„ํš์€ ์—ฌ๋Ÿฌ ๊ฐ€์ง€๊ฐ€ ๋  ์ˆ˜ ์žˆ๊ณ ,
์˜ตํ‹ฐ๋งˆ์ด์ €๊ฐ€ ํ†ต๊ณ„ ์ •๋ณด์™€ ๋น„์šฉ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์‹คํ–‰ ๋ฐฉ๋ฒ•์„ ์„ ํƒํ•œ๋‹ค๋Š” ์ ์ด ์ธ์ƒ ๊นŠ์—ˆ๋‹ค.

์ด์ „์—๋Š” EXPLAIN ๊ฒฐ๊ณผ๋ฅผ ๋ณด๋”๋ผ๋„
type, Extra, Using filesort ๊ฐ™์€ ํ•ญ๋ชฉ๋“ค์ด ๋‹จ์ˆœํ•œ ์šฉ์–ด์ฒ˜๋Ÿผ ๋А๊ปด์กŒ๋‹ค๋ฉด,
์ด์ œ๋Š” ์™œ ์ด๋Ÿฐ ์‹คํ–‰๊ณ„ํš์ด ๋‚˜์™”๋Š”์ง€,
๊ทธ๋ฆฌ๊ณ  ์ฟผ๋ฆฌ๋ฅผ ์–ด๋–ป๊ฒŒ ๋ฐ”๊พธ๋ฉด ์˜ตํ‹ฐ๋งˆ์ด์ €์˜ ์„ ํƒ์ด ๋‹ฌ๋ผ์งˆ์ง€๋ฅผ ๊ณ ๋ฏผํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ๋‹ค.

๋˜ํ•œ ๋‹จ์ˆœํžˆ โ€œ์ธ๋ฑ์Šค๋ฅผ ์“ฐ๋ฉด ๋น ๋ฅด๋‹คโ€๊ฐ€ ์•„๋‹ˆ๋ผ,

  • ์–ธ์ œ ํ’€ ํ…Œ์ด๋ธ” ์Šค์บ”์ด ๋” ๋‚˜์„ ์ˆ˜ ์žˆ๋Š”์ง€
  • ORDER BY / GROUP BY์—์„œ ์ธ๋ฑ์Šค๊ฐ€ ์–ด๋–ป๊ฒŒ ํ™œ์šฉ๋˜๋Š”์ง€
  • ํŒŒ์ผ์†ŒํŠธ์™€ ์ž„์‹œ ํ…Œ์ด๋ธ”์ด ์™œ ์„ฑ๋Šฅ ๋ณ‘๋ชฉ์ด ๋˜๋Š”์ง€

๊ฐ™์€ DB์˜ ๊ธฐ๋ณธ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ๋ฐฉ์‹์„ ์ž์„ธํžˆ ์ดํ•ดํ•ด๋ณผ ์ˆ˜ ์žˆ์—ˆ๋˜ ์˜๋ฏธ์žˆ๋Š” ์‹œ๊ฐ„์ด์—ˆ๋˜ ๊ฒƒ ๊ฐ™๋‹ค.

[์ฐธ๊ณ ์ž๋ฃŒ]

https://dev.mysql.com/doc/refman/8.4/en/optimization.html
Real MySQL 8.0
https://velog.io/@kwontae1313/์˜ตํ‹ฐ๋งˆ์ด์ €
https://velog.io/@cham-chi/DB-๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค-์ฟผ๋ฆฌ-์˜ตํ‹ฐ๋งˆ์ด์ €Query-Optimizer์—-๋Œ€ํ•˜์—ฌ

0๊ฐœ์˜ ๋Œ“๊ธ€