๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
CS/Database

MySQL EXPLAIN ์‹คํ–‰๊ณ„ํš ๋งˆ์Šคํ„ฐํ•˜๊ธฐ(feat. RealMySQL 8.0)

by ์ฃผ๋ฐœ2 2023. 1. 7.
๋ฐ˜์‘ํ˜•

๐Ÿ’ฏ  MySQL EXPLAIN ์‹คํ–‰๊ณ„ํš ๋งˆ์Šคํ„ฐํ•˜๊ธฐ(feat. RealMySQL 8.0)

์‹คํ–‰ ๊ณ„ํš(EXPLAIN) ์ด๋ž€?

๋Œ€๋ถ€๋ถ„์˜ DBMS๋Š” ๋งŽ์€ ๋ฐ์ดํ„ฐ๋ฅผ ์•ˆ์ „ํ•˜๊ณ , ๋น ๋ฅด๊ฒŒ ์ €์žฅ ๋ฐ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ์ฃผ๋ชฉ์ ์ด๋‹ค.

์ด๋Ÿฌํ•œ ๋ชฉ์ ์„ ๋‹ฌ์„ฑํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ์ž์˜ ์ฟผ๋ฆฌ๋ฅผ ์˜ตํ‹ฐ๋งˆ์ด์ €๊ฐ€ ์ตœ์ ์œผ๋กœ ์ฒ˜๋ฆฌ๋  ์ˆ˜ ์žˆ๋„๋ก ์ฟผ๋ฆฌ์˜ ์‹คํ–‰ ๊ณ„ํš์„ ์ˆ˜๋ฆฝํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค.

ํ•˜์ง€๋งŒ ์˜ตํ‹ฐ๋งˆ์ด์ €๊ฐ€ ํ•ญ์ƒ ์ตœ์ ์˜ ์‹คํ–‰ ๊ณ„ํš์„ ๋งŒ๋“ค์–ด๋‚ผ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋ฏ€๋กœ DBMS ์„œ๋ฒ„๋Š” ์ด๋Ÿฌํ•œ ๋ฌธ์ œ์ ์„ ๊ด€๋ฆฌ์ž๋‚˜ ์‚ฌ์šฉ์ž๊ฐ€ ๋ณด์™„ํ•  ์ˆ˜ ์žˆ๋„๋ก EXPLAIN ๋ช…๋ น์œผ๋กœ ์˜ตํ‹ฐ๋งˆ์ด์ €๊ฐ€ ์ˆ˜๋ฆฝํ•œ ์‹คํ–‰ ๊ณ„ํš์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

 

ํ…Œ์ŠคํŠธ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค: https://github.com/datacharmer/test_db

์‹คํ–‰ ๊ณ„ํš ์˜๋ฏธ
id SELECT ์ฟผ๋ฆฌ ๋ณ„ ๋ถ€์—ฌ๋˜๋Š” ์‹๋ณ„์ž ๊ฐ’
select_type ๊ฐ ๋‹จ์œ„ SELECT ์ฟผ๋ฆฌ๊ฐ€ ์–ด๋–ค ํƒ€์ž…์˜ ์ฟผ๋ฆฌ์ธ์ง€ ํ‘œ์‹œ๋˜๋Š” ์นผ๋Ÿผ
table ์ ‘๊ทผํ•˜๊ณ  ์žˆ๋Š” ํ…Œ์ด๋ธ”์— ๋Œ€ํ•œ ํ‘œ์‹œ
partitions ํ…Œ์ด๋ธ”์— ํŒŒํ‹ฐ์…”๋‹์ด ๋˜์–ด ์žˆ๋Š” ๊ฒฝ์šฐ ์‚ฌ์šฉ๋˜๋Š” ํ•„๋“œ
type ๊ฐ ํ…Œ์ด๋ธ”์˜ ๋ ˆ์ฝ”๋“œ๋ฅผ ์–ด๋–ป๊ฒŒ ์ฝ์—ˆ๋Š”์ง€์— ๋Œ€ํ•œ ์ ‘๊ทผ ๋ฐฉ์‹
possible_keys “์‚ฌ์šฉ๋  ๋ฒ•ํ–ˆ๋˜ ์ธ๋ฑ์Šค์˜ ๋ชฉ๋ก”์ด๋ฉฐ ๋ฐ˜๋“œ์‹œ ์‚ฌ์šฉ๋œ ๊ฒƒ์€ ์•„๋‹˜
key ์ตœ์ข… ์„ ํƒ๋œ ์‹คํ–‰ ๊ณ„ํš์—์„œ ์‚ฌ์šฉ๋˜๋Š” ์ธ๋ฑ์Šค
key_len ์„ ํƒ๋œ ์ธ๋ฑ์Šค์˜ ๊ธธ์ด๋ฅผ ์˜๋ฏธ
ref ์ ‘๊ทผ ๋ฐฉ๋ฒ•์ด ref๋ฉด ์ฐธ์กฐ ์กฐ๊ฑด(equal ๋น„๊ต ์กฐ๊ฑด)์œผ๋กœ ์–ด๋–ค ๊ฐ’์ด ์ œ๊ณต๋๋Š”์ง€ ํ‘œ์‹œ
rows ์‹คํ–‰ ๊ณ„ํš์˜ ํšจ์œจ์„ฑ ํŒ๋‹จ์„ ์œ„ํ•ด ์˜ˆ์ธกํ–ˆ๋˜ ๋ ˆ์ฝ”๋“œ ๊ฑด์ˆ˜๋ฅผ ๋ณด์—ฌ์ค€๋‹ค. (์ •ํ™•ํ•˜์ง€๋Š” ์•Š์Œ)
filtered ํ•„ํ„ฐ๋ง๋˜๊ณ  ๋‚จ์€ ๋ ˆ์ฝ”๋“œ์˜ ๋น„์œจ (์ •ํ™•ํ•˜์ง€๋Š” ์•Š์Œ)
Extra ์˜ตํ‹ฐ๋งˆ์ด์ €๊ฐ€ ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๋Š”์ง€์— ๋Œ€ํ•ด ์•Œ๋ ค์ฃผ๋Š” ํžŒํŠธ ๊ฐ’

 

์‹คํ–‰ ๊ณ„ํš ๋ถ„์„

EXPLAIN ๋ช…๋ น์œผ๋กœ MySQL์—์„œ ์‹คํ–‰ ๊ณ„ํš์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ ์ด๋Š” ์ฟผ๋ฆฌ ๋ฌธ์žฅ์—์„œ ์‚ฌ์šฉ๋œ ํ…Œ์ด๋ธ”์˜ ๊ฐฏ์ˆ˜๋งŒํผ ์ถœ๋ ฅํ•œ๋‹ค.

 

๐Ÿ”—  1. id

  • SELECT ์ฟผ๋ฆฌ ๋ณ„ ๋ถ€์—ฌ๋˜๋Š” ์‹๋ณ„์ž ๊ฐ’

 

 

๐Ÿ”—  2. select_type

  • ๊ฐ ๋‹จ์œ„ SELECT ์ฟผ๋ฆฌ๊ฐ€ ์–ด๋–ค ํƒ€์ž…์˜ ์ฟผ๋ฆฌ์ธ์ง€ ํ‘œ์‹œ๋˜๋Š” ์นผ๋Ÿผ

2.1 SIMPLE

  • ๋‹จ์ˆœ SELECT ์ฟผ๋ฆฌ
  • ์ฟผ๋ฆฌ ๋ฌธ์žฅ์ด ์•„๋ฌด๋ฆฌ ๋ณต์žกํ•˜๋”๋ผ๋„ ์‹คํ–‰ ๊ณ„ํš์—์„œ select_type์ด SIMPLE์ธ ๋‹จ์œ„ ์ฟผ๋ฆฌ๋Š” ์ตœ๋Œ€ ํ•˜๋‚˜๋งŒ ์กด์žฌ

2.2 PRIMARY

  • UNION์ด๋‚˜ ์„œ๋ธŒ์ฟผ๋ฆฌ๋ฅผ ๊ฐ€์ง€๋Š” SELECT ์ฟผ๋ฆฌ์˜ ์‹คํ–‰ ๊ณ„ํš์—์„œ ๊ฐ€์žฅ ๋ฐ”๊นฅ์ชฝ์— ์žˆ๋Š” ๋‹จ์œ„ ์ฟผ๋ฆฌ
  • SIMPLE์™€ ๋งˆ์ฐฌ๊ฐ€์ง€ ์ตœ๋Œ€ ํ•˜๋‚˜๋งŒ ์กด์žฌ

2.3 UNION

  • UNION์œผ๋กœ ๊ฒฐํ•ฉํ•˜๋Š” ๋‹จ์œ„ SELECT ์ฟผ๋ฆฌ ๊ฐ€์šด๋ฐ ์ฒซ ๋ฒˆ์งธ๋ฅผ ์ œ์™ธํ•œ ๋‘ ๋ฒˆ์งธ ์ดํ›„ ์ฟผ๋ฆฌ๋“ค
  • UNION์˜ ์ฒซ ๋ฒˆ์งธ ๋‹จ์œ„ SELECT๋Š” UNION๋˜๋Š” ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ๋“ค์„ ๋ชจ์•„์„œ ์ €์žฅํ•˜๋Š” ์ž„์‹œ ํ…Œ์ด๋ธ”(DERIVED)

๐Ÿ’ก Quiz 1. ์œ„ ์ฟผ๋ฆฌ์—์„œ DERIVED ํƒ€์ž…๊ณผ UNION ํƒ€์ž…์€ ๊ฐ๊ฐ ์–ด๋–ค ์ฟผ๋ฆฌ๋“ค์ผ๊นŒ?

๋”๋ณด๊ธฐ

-- 1. DERIVED

-- 2. UNION
-- 3. UNION

DERIVED & UNION
  • <>๋กœ ๋‘˜๋Ÿฌ์‹ธ์ธ ์ด๋ฆ„์ด ๋ช…์‹œ๋˜๋Š” ๊ฒฝ์šฐ ์ž„์‹œ ํ…Œ์ด๋ธ”์„ ์˜๋ฏธํ•จ
    • <derived2> → id ๊ฐ’์ด 2์ธ ์‹คํ–‰ ๊ณ„ํš์œผ๋กœ๋ถ€ํ„ฐ ๋งŒ๋“ค์–ด์ง„ ํŒŒ์ƒ(DERIVED) ํ…Œ์ด๋ธ”

2.4 DEPENDENT UNION

  • DEPENDENT๋Š” UNION์ด๋‚˜ UNION ALL๋กœ ๊ฒฐํ•ฉ๋œ ๋‹จ์œ„ ์ฟผ๋ฆฌ๊ฐ€ ์™ธ๋ถ€ ์ฟผ๋ฆฌ์— ์˜ํ•ด ์˜ํ–ฅ์„ ๋ฐ›๋Š” ๊ฒƒ
  • ์•„๋ž˜ ์ฟผ๋ฆฌ์—์„œ ์˜ตํ‹ฐ๋งˆ์ด์ €๋Š” IN ๋‚ด๋ถ€์˜ ์„œ๋ธŒ์ฟผ๋ฆฌ๋ฅผ ๋จผ์ € ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š๊ณ , ์™ธ๋ถ€์˜ employees ํ…Œ์ด๋ธ”์„ ๋จผ์ € ์ฝ์€ ํ›„ ์„œ๋ธŒ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰
  • ์ด๋•Œ employees ํ…Œ์ด๋ธ”์˜ ์นผ๋Ÿผ๊ฐ’์ด ์„œ๋ธŒ์ฟผ๋ฆฌ์— ์˜ํ–ฅ์„ ์คŒ
  • (๋‚ด๋ถ€ ์ฟผ๋ฆฌ๊ฐ€ ์™ธ๋ถ€์˜ ๊ฐ’์„ ์ฐธ์กฐํ•ด์„œ ์ฒ˜๋ฆฌ๋  ๋•Œ)

2.5 UNION RESULT

  • UNION RESULT๋Š” UNION ๊ฒฐ๊ณผ๋ฅผ ๋‹ด์•„๋‘๋Š” ํ…Œ์ด๋ธ”
  • <union2,3> : id ๊ฐ’์ด 2, 3 ์ฟผ๋ฆฌ์˜ ์กฐํšŒ ๊ฒฐ๊ณผ๋ฅผ UNION

2.4 ์ฟผ๋ฆฌ์™€ ๋™์ผ

2.6 SUBQUERY

  • select_type์˜ SUBQUERY๋Š” FROM ์ ˆ ์ด์™ธ์—์„œ ์‚ฌ์šฉ๋˜๋Š” ์„œ๋ธŒ์ฟผ๋ฆฌ๋งŒ์„ ์˜๋ฏธํ•จ

๐Ÿ’ก Quiz 2. ์„œ๋ธŒ์ฟผ๋ฆฌ์˜ ์ข…๋ฅ˜๋Š” ์–ด๋– ํ•œ ๊ฒƒ๋“ค์ด ์žˆ์„๊นŒ? (Hint: SELECT, FROM, WHERE ์ ˆ)

๋”๋ณด๊ธฐ
  • SELECT: ์Šค์นผ๋ผ ์„œ๋ธŒ์ฟผ๋ฆฌ
  • FROM: ์ธ๋ผ์ธ ๋ทฐ
  • WHERE: ์ค‘์ฒฉ ์„œ๋ธŒ์ฟผ๋ฆฌ

2.8 DERIVED

  • DERIVED๋Š” ๋‹จ์œ„ SELECT ์ฟผ๋ฆฌ์˜ ์‹คํ–‰ ๊ฒฐ๊ณผ๋กœ ๋ฉ”๋ชจ๋ฆฌ๋‚˜ ๋””์Šคํฌ์— ์ž„์‹œ ํ…Œ์ด๋ธ”์„ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ
  • select_type์ด DERIVED์ธ ๊ฒฝ์šฐ์— ์ƒ์„ฑ๋˜๋Š” ์ž„์‹œ ํ…Œ์ด๋ธ”์„ ํŒŒ์ƒ ํ…Œ์ด๋ธ”์ด๋ผ๊ณ ๋„ ํ•จ
  • MySQL 5.6 ๋ฒ„์ „๋ถ€ํ„ฐ๋Š” ์˜ตํ‹ฐ๋งˆ์ด์ € ์˜ต์…˜์— ๋”ฐ๋ผ ์ด์ „ ๋ฒ„์ „๊ณผ๋Š” ๋‹ฌ๋ฆฌ ์ž„์‹œ ํ…Œ์ด๋ธ”์—๋„ ์ธ๋ฑ์Šค๋ฅผ ์ถ”๊ฐ€ํ•ด์„œ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ฒŒ ์ตœ์ ํ™”๋จ

  • MySQL ์„œ๋ฒ„๋Š” ๋ฒ„์ „์ด ์—…๊ทธ๋ ˆ์ด๋“œ๋˜๋ฉด์„œ ์กฐ์ธ ์ฟผ๋ฆฌ์— ๋Œ€ํ•œ ์ตœ์ ํ™”๋Š” ๋งŽ์ด ์„ฑ์ˆ™๋œ ์ƒํƒœ
  • ํŒŒ์ƒ ํ…Œ์ด๋ธ”(DERIVED)์— ๋Œ€ํ•œ ์ตœ์ ํ™”๊ฐ€ ๋ถ€์กฑํ•œ ๋ฒ„์ „์˜ MySQL ์„œ๋ฒ„๋ฅผ ์‚ฌ์šฉ ์ค‘์ผ ๊ฒฝ์šฐ(MySQL 5.x ๋ฒ„์ „), ๊ฐ€๋Šฅํ•˜๋‹ค๋ฉด DERIVED ํ˜•ํƒœ์˜ ์‹คํ–‰ ๊ณ„ํš์„ ์กฐ์ธ์œผ๋กœ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๊ฒŒ ์ฟผ๋ฆฌ๋ฅผ ๋ฐ”๊ฟ”์ฃผ๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.
    • ๊ฐ€์žฅ ์ข‹์€ ๋ฐฉ๋ฒ•์€ ์‹คํ–‰ ๊ณ„ํš์„ ํ™•์ธํ•ด๋ณด๊ณ  ๊ฒฐ์ •ํ•˜๋Š” ๊ฒƒ
๐Ÿ’ก ํ•œ์ค„ ์š”์•ฝ: ์„œ๋ธŒ์ฟผ๋ฆฌ ๋Œ€์‹  ์กฐ์ธ์„ ์‚ฌ์šฉํ•˜์ž

์ฟผ๋ฆฌ๋ฅผ ํŠœ๋‹ํ•˜๊ธฐ ์œ„ํ•ด ์‹คํ–‰ ๊ณ„ํš์„ ํ™•์ธํ•  ๋•Œ ๊ฐ€์žฅ ๋จผ์ € select_type ์ปฌ๋Ÿผ์˜ ๊ฐ’์ด DERIVED์ธ ๊ฒƒ์ด ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๊ณ , ์„œ๋ธŒ์ฟผ๋ฆฌ๋ฅผ ์กฐ์ธ์œผ๋กœ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ๋ผ๋ฉด ์„œ๋ธŒ์ฟผ๋ฆฌ๋ณด๋‹ค๋Š” ์กฐ์ธ์„ ์‚ฌ์šฉํ•  ๊ฒƒ์„ ๊ฐ•๋ ฅํžˆ ๊ถŒ์žฅํ•œ๋‹ค. -Real MySQL 8.0 -

2.12 MATERIALIZED

  • MySQL 5.6 ๋ฒ„์ „๋ถ€ํ„ฐ ๋„์ž…๋œ select_type์œผ๋กœ ์ฃผ๋กœ FROM์ ˆ, In(Subquery) ํ˜•ํƒœ์˜ ์ฟผ๋ฆฌ์—์„œ ํฌํ•จ๋˜์–ด ์žˆ๋Š” ์„œ๋ธŒ์ฟผ๋ฆฌ์˜ ์ตœ์ ํ™”๋ฅผ ์œ„ํ•ด ์‚ฌ์šฉ
  • MySQL 5.6 ๋ฒ„์ „๊นŒ์ง€๋Š” employees ํ…Œ์ด๋ธ”์„ ์ฝ์–ด์„œ employees ํ…Œ์ด๋ธ”์˜ ๋ ˆ์ฝ”๋“œ๋งˆ๋‹ค salaries ํ…Œ์ด๋ธ”์„ ์ฝ๋Š” ์„œ๋ธŒ์ฟผ๋ฆฌ๊ฐ€ ์‹คํ–‰๋˜๋Š” ํ˜•ํƒœ๋กœ ์ฒ˜๋ฆฌ๋๋‹ค. (Table Full Scan)
  • MySQL 5.7 ๋ฒ„์ „๋ถ€ํ„ฐ ์„œ๋ธŒ์ฟผ๋ฆฌ์˜ ๋‚ด์šฉ์„ ์ž„์‹œ ํ…Œ์ด๋ธ”๋กœ ๊ตฌ์ฒดํ™”(Materialization) ํ•œ ํ›„ ์ž„์‹œ ํ…Œ์ด๋ธ” ์‚ฌ์šฉ
  • MySQL 5.6 Switchable Optimizations(semijoin=on)

(์œ„ ์ตœ์ ํ™”๊ฐ€ ์–ด๋Š์ •๋„์˜ ์ฐจ์ด๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ์ง€๋Š” ์•„๋ž˜ *5.7์˜ ์˜ˆ์‹œ ์ฐธ๊ณ )

https://engineering.linecorp.com/ko/blog/mysql-workbench-visual-explain-index/

 

๐Ÿ”—  3. table

  • ์ ‘๊ทผํ•˜๊ณ  ์žˆ๋Š” ํ…Œ์ด๋ธ”์— ๋Œ€ํ•œ ํ‘œ์‹œ
  • MySQL ์„œ๋ฒ„์˜ ์‹คํ–‰ ๊ณ„ํš์€ ๋‹จ์œ„ SELECT ์ฟผ๋ฆฌ ๊ธฐ์ค€์ด ์•„๋‹Œ ํ…Œ์ด๋ธ” ๊ธฐ์ค€์œผ๋กœ ํ‘œ์‹œ๋œ๋‹ค.
  • ํ…Œ์ด๋ธ”์˜ ์ด๋ฆ„์— ๋ณ„์นญ์ด ๋ถ€์—ฌ๋œ ๊ฒฝ์šฐ์—๋Š” ๋ณ„์นญ ํ‘œ์‹œ

๐Ÿ’ก Quiz 3. ์‹คํ–‰ ๊ณ„ํš์„ ํ†ตํ•ด ์ฟผ๋ฆฌ๋ฅผ ์œ ์ถ”ํ•ด๋ณด์ž.

๋”๋ณด๊ธฐ
  1. ์ฒซ ๋ฒˆ์งธ ๋ผ์ธ์˜ <derived2>๋ฅผ ํ†ตํ•ด id = 2์ธ ๋ผ์ธ์ด ๋จผ์ € ์‹คํ–‰๋˜๊ณ , ๊ทธ ๊ฒฐ๊ณผ๊ฐ€ ํŒŒ์ƒ ํ…Œ์ด๋ธ”๋กœ ์ค€๋น„
  2. ์„ธ ๋ฒˆ์งธ ๋ผ์ธ(id = 2)์„ ๋ณด๋ฉด select_type = DERIVED, table = s ์ด๋ฏ€๋กœ salaries(๋ณ„์นญ: s) ํ…Œ์ด๋ธ”์„ ์ฝ์–ด์„œ ํŒŒ์ƒ ํ…Œ์ด๋ธ” ์ƒ์„ฑ
    • SELECT ~ FROM salaries s
  3. ์ฒซ ๋ฒˆ์งธ ๋ผ์ธ๊ณผ ๋‘ ๋ฒˆ์งธ ๋ผ์ธ์€ ๊ฐ™์€ id ๊ฐ’์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š”๊ฒƒ์œผ๋กœ ๋ณด์•„ 2๊ฐœ ํ…Œ์ด๋ธ”์ด ์กฐ์ธ๋œ ์ฟผ๋ฆฌ(e, s ํ…Œ์ด๋ธ”)์ธ ๊ฑธ ์•Œ ์ˆ˜ ์žˆ์Œ
    • FROM employees e JOIN SELECT ~ FROM salaries s ON ~
  4. <derived 2> ํ…Œ์ด๋ธ”์ด e ํ…Œ์ด๋ธ”๋ณด๋‹ค ๋จผ์ €(์œ„์—) ํ‘œ์‹œ๋๊ธฐ ๋•Œ๋ฌธ์— <derived 2>๊ฐ€ ๋“œ๋ผ์ด๋น™ ํ…Œ์ด๋ธ”์ด ๋˜๊ณ  e ํ…Œ์ด๋ธ”์ด ๋“œ๋ฆฌ๋ธ ํ…Œ์ด๋ธ”์ด ๋œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.
    • ๋ณดํ†ต ์˜ตํ‹ฐ๋งˆ์ด์ €๋Š” ํ…Œ์ด๋ธ” ์กฐ์ธ ์‹œ ๋ ˆ์ฝ”๋“œ๊ฐ€ ์ ์€ ํ…Œ์ด๋ธ”์„ ๋จผ์ € ์ฝ์Œ(๋“œ๋ผ์ด๋น™ ํ…Œ์ด๋ธ”)

 

*์œ„ ์‹คํ–‰ ๊ณ„ํš์„ ํ†ตํ•ด ์•„๋ž˜ ์ฟผ๋ฆฌ๊ฐ€ ์‹คํ–‰๋˜๋Š” ๊ฒƒ์„ ์œ ์ถ”ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

๐Ÿ”—  4. partitions

  • ํ…Œ์ด๋ธ”์— ํŒŒํ‹ฐ์…”๋‹์ด ๋˜์–ด ์žˆ๋Š” ๊ฒฝ์šฐ ์‚ฌ์šฉ๋˜๋Š” ํ•„๋“œ
    • ์‰ฝ๊ฒŒ ๋งํ•˜๋ฉด ๋™์ผํ•œ ํ…Œ์ด๋ธ”์— ๋ฐ์ดํ„ฐ๋ฅผ ๋ถ„ํ• ํ•˜์—ฌ ์ €์žฅํ•˜๋Š” ๋ฐฉ์‹
  • ~ MySQL 5.7 ๋ฒ„์ „ : EXPLAIN PARTITION
  • MySQL 8.0 ๋ฒ„์ „๋ถ€ํ„ฐ๋Š” EXPLAIN ๋ช…๋ น์œผ๋กœ ํŒŒํ‹ฐ์…˜ ๊ด€๋ จ ์‹คํ–‰ ๊ณ„ํš๊นŒ์ง€ ํ™•์ธ ๊ฐ€๋Šฅ

  • ์˜ตํ‹ฐ๋งˆ์ด์ €๋Š” ์ฟผ๋ฆฌ์˜ hire_date ์นผ๋Ÿผ ์กฐ๊ฑด์„ ๋ณด๊ณ , ์ฟผ๋ฆฌ์—์„œ ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋Š” p2015, p2020 ํŒŒํ‹ฐ์…˜์—๋งŒ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ํŒŒ์•… → ํ•ด๋‹น ํŒŒํ‹ฐ์…˜๋งŒ ์Šค์บ”
  • ํŒŒํ‹ฐ์…˜ ํ”„๋ฃจ๋‹ : ์ฟผ๋ฆฌ ์ˆ˜ํ–‰์„ ์œ„ํ•ด ์ ‘๊ทผํ•ด์•ผ ํ•  ํ…Œ์ด๋ธ”๋งŒ ๊ณจ๋ผ๋‚ด๋Š” ๊ณผ์ •
  • type์„ ๋ณด๋ฉด ALL์ด๋ผ ํ’€ ํ…Œ์ด๋ธ” ์Šค์บ”์œผ๋กœ ์ฒ˜๋ฆฌ๊ฐ€ ๋˜๋Š”๋ฐ, MySQL ํฌํ•จ ๋Œ€๋ถ€๋ถ„ RDBMS์—์„œ ์ง€์›ํ•˜๋Š” ํŒŒํ‹ฐ์…˜์€ ๋ฌผ๋ฆฌ์ ์œผ๋กœ ๊ฐœ๋ณ„ ํ…Œ์ด๋ธ”์ฒ˜๋Ÿผ ๋ณ„๋„์˜ ์ €์žฅ ๊ณต๊ฐ„์„ ๊ฐ€์ง€๊ธฐ ๋•Œ๋ฌธ
  • ์œ„ ์ฟผ๋ฆฌ๋Š” employees_partitions ํ…Œ์ด๋ธ”์˜ ํŠน์ • ํŒŒํ‹ฐ์…˜(p2015, p2020)๋งŒ ํ’€ ์Šค์บ”์„ ์‹คํ–‰

 

๐Ÿ”—  5. type

  • ๊ฐ ํ…Œ์ด๋ธ”์˜ ๋ ˆ์ฝ”๋“œ๋ฅผ ์–ด๋–ป๊ฒŒ ์ฝ์—ˆ๋Š”์ง€์— ๋Œ€ํ•œ ์ ‘๊ทผ ๋ฐฉ์‹
    • ๋ฐฉ์‹ → ์ธ๋ฑ์Šค, ํ’€ ํ…Œ์ด๋ธ” ์Šค์บ”, ์ธ๋ฑ์Šค ํ’€ ์Šค์บ” ๋“ฑ๋“ฑ
  • ์ฟผ๋ฆฌ ํŠœ๋‹ ์‹œ ๋ฐ˜๋“œ์‹œ ์ฒดํฌํ•ด์•ผ ํ•  ์ค‘์š”ํ•œ ์ •๋ณด
  • type ์นผ๋Ÿผ์— ํ‘œ์‹œ๋  ์ˆ˜ ์žˆ๋Š” ๊ฐ’๋“ค .. (12๊ฐœ)
    • system, const, eq_ref, ref, fulltext, ref_or_null, unique_subquery, index_subquery, range, index_merge, index, ALL
  • ALL(ํ…Œ์ด๋ธ” ํ’€ ์Šค์บ”)์„ ์ œ์™ธํ•œ ๋‚˜๋จธ์ง€๋Š” ๋ชจ๋‘ ์ธ๋ฑ์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ ‘๊ทผ ๋ฐฉ์‹
  • system → ALL ๊ฐˆ์ˆ˜๋ก ์„ฑ๋Šฅ์ด ๋Š๋ ค์ง
  • MySQL ์˜ตํ‹ฐ๋งˆ์ด์ €๋Š” ์ด๋Ÿฌํ•œ ์ ‘๊ทผ ๋ฐฉ๋ฒ•๊ณผ ๋น„์šฉ์„ ํ•จ๊ป˜ ๊ณ„์‚ฐํ•ด์„œ ์ตœ์†Œ์˜ ๋น„์šฉ์ด ํ•„์š”ํ•œ ์ ‘๊ทผ ๋ฐฉ๋ฒ•์„ ์„ ํƒํ•ด ์ฟผ๋ฆฌ๋ฅผ ์ฒ˜๋ฆฌํ•จ

5.1 system

  • ํ…Œ์ด๋ธ”์˜ ๋ ˆ์ฝ”๋“œ๊ฐ€ ์ตœ๋Œ€ 1๊ฑด ์กด์žฌํ•˜๋Š” ํ…Œ์ด๋ธ”์„ ์ฐธ์กฐํ•˜๋Š” ํ˜•ํƒœ์˜ ์ ‘๊ทผ ๋ฐฉ๋ฒ•
  • InnoDB ์Šคํ† ๋ฆฌ์ง€ ์—”์ง„์—์„œ๋Š” ๋‚˜ํƒ€๋‚˜์ง€ ์•Š๊ณ , MyISAM/MEMORY ํ…Œ์ด๋ธ”์—์„œ๋งŒ ์‚ฌ์šฉ๋˜๋Š” ์ ‘๊ทผ ๋ฐฉ์‹
  • ํ…Œ์ด๋ธ”์— ๋ ˆ์ฝ”๋“œ๊ฐ€ 1๊ฑด ์ดํ•˜์ธ ๊ฒฝ์šฐ์—๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ธฐ์— ๊ฑฐ์˜ ๋ณด์ด์ง€ ์•Š์Œ

ENGINE = MyISAM
ENGINE = InnoDB

5.2 const

  • ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ๊ฐ€ ๋ฐ˜๋“œ์‹œ 1๊ฑด์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ฟผ๋ฆฌ์˜ ์ฒ˜๋ฆฌ ๋ฐฉ์‹
    • PK ๋ฐ Unique Key ์ปฌ๋Ÿผ์„ ์ด์šฉํ•˜๋Š” ์กฐ๊ฑด์ ˆ

 

  • ์•„๋ž˜ ์ฒ˜๋Ÿผ ๋‹ค์ค‘ ์นผ๋Ÿผ์œผ๋กœ ๊ตฌ์„ฑ๋œ PK์—์„œ ์ผ๋ถ€ ์นผ๋Ÿผ๋งŒ ์กฐ๊ฑด์œผ๋กœ ์‚ฌ์šฉํ•  ๋•Œ๋Š” const ์ ‘๊ทผ ๋ฐฉ์‹ ๋ถˆ๊ฐ€๋Šฅ
  • ์‹ค์ œ ๋ ˆ์ฝ”๋“œ๊ฐ€ 1๊ฑด๋งŒ ์ €์žฅ๋˜์–ด ์žˆ๋”๋ผ๋„ MySQL ์—”์ง„์ด ํ…Œ์ด๋ธ”์„ ์ฝ๊ธฐ ์ „์—๋Š” ๋ ˆ์ฝ”๋“œ๊ฐ€ 1๊ฑด์ด๋ผ๋Š” ๊ฒƒ์„ ํ™•์‹ ํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ
  • PK์˜ ์ผ๋ถ€๋งŒ ์กฐ๊ฑด์œผ๋กœ ์‚ฌ์šฉํ•  ๋•Œ๋Š” type ์นผ๋Ÿผ์— ref๋กœ ํ‘œ์‹œ

 

PK์˜ ๋ชจ๋“  ์นผ๋Ÿผ์„ ๋™๋“ฑ ์กฐ๊ฑด์œผ๋กœ WHERE ์ ˆ์— ๋ช…์‹œํ•˜๋ฉด const ์ ‘๊ทผ ๋ฐฉ์‹ ์‚ฌ์šฉ

5.3 eq_ref

  • ์—ฌ๋Ÿฌ ํ…Œ์ด๋ธ”์ด ์กฐ์ธ๋˜๋Š” ์ฟผ๋ฆฌ์˜ ์‹คํ–‰ ๊ณ„ํš์—์„œ๋งŒ ํ‘œ์‹œ
  • ์กฐ์ธ์—์„œ ์ฒ˜์Œ ์ฝ์€ ํ…Œ์ด๋ธ”์˜ ์นผ๋Ÿผ๊ฐ’์„, ๋‹ค์Œ ์ฝ์„ ํ…Œ์ด๋ธ”์˜ PK๋‚˜ ์œ ๋‹ˆํฌ ํ‚ค ์นผ๋Ÿผ์˜ ๊ฒ€์ƒ‰ ์กฐ๊ฑด์— ์‚ฌ์šฉํ•  ๋•Œ eq_ref ์ ‘๊ทผ๋ฐฉ์‹ ์‚ฌ์šฉ
  • ๋‘ ๋ฒˆ์งธ ์ดํ›„์— ์ฝ๋Š” ํ…Œ์ด๋ธ”์˜ type ์นผ๋Ÿผ์— eq_ref๊ฐ€ ํ‘œ์‹œ
  • ์กฐ์ธ์—์„œ ๋‘ ๋ฒˆ์งธ ์ดํ›„์— ์ฝ๋Š” ํ…Œ์ด๋ธ”์—์„œ ๋ฐ˜๋“œ์‹œ 1๊ฑด๋งŒ ์กด์žฌํ•œ๋‹ค๋Š” ๋ณด์žฅ์ด ์žˆ์–ด์•ผ ์‚ฌ์šฉ

5.4 ref

  • ์กฐ์ธ์˜ ์ˆœ์„œ์™€ ๊ด€๊ณ„์—†์ด ๋™๋“ฑ(Equal) ์กฐ๊ฑด์œผ๋กœ ๊ฒ€์ƒ‰ํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ์ ‘๊ทผ ๋ฐฉ์‹
  • ref ํƒ€์ž…์€ ๋ฐ˜ํ™˜๋˜๋Š” ๋ ˆ์ฝ”๋“œ๊ฐ€ ๋ฐ˜๋“œ์‹œ 1๊ฑด์ด๋ผ๋Š” ๋ณด์žฅ์ด ์—†์œผ๋ฏ€๋กœ const, eq_ref ๋ณด๋‹ค๋Š” ๋Š๋ฆฌ์ง€๋งŒ ๋™๋“ฑํ•œ ์กฐ๊ฑด์œผ๋กœ๋งŒ ๋น„๊ต๋˜๊ธฐ์— ๋งค์šฐ ๋น ๋ฅธ ๋ ˆ์ฝ”๋“œ ์กฐํšŒ ๋ฐฉ๋ฒ• ์ค‘ ํ•˜๋‚˜

 

๐Ÿ’ก const, ref ์ •๋ฆฌ

  • const: ๋ชจ๋“  ์ปฌ๋Ÿผ์— ๋Œ€ํ•ด PK, ์œ ๋‹ˆํฌ ํ‚ค ๋“ฑ ๋™๋“ฑ ์กฐ๊ฑด์œผ๋กœ ๊ฒ€์ƒ‰(๋ฐ˜๋“œ์‹œ 1๊ฑด์˜ ๋ ˆ์ฝ”๋“œ๋งŒ ๋ฐ˜ํ™˜)
  • ref: ๋™๋“ฑ ์กฐ๊ฑด์œผ๋กœ ๊ฒ€์ƒ‰(1๊ฑด์˜ ๋ ˆ์ฝ”๋“œ๋งŒ ๋ฐ˜ํ™˜๋œ๋‹ค๋Š” ๋ณด์žฅ์ด ์—†์–ด๋„ ๋จ)
  • const, eq_ref, ref์€ ์ข‹์€ ์ ‘๊ทผ ๋ฐฉ๋ฒ•์œผ๋กœ ํฌ๊ฒŒ ์‹ ๊ฒฝ์“ฐ์ง€ ์•Š๊ณ  ๋„˜์–ด๊ฐ€๋„ ๋ฌด๋ฐฉ

5.5 fulltext

  • fulltext ์ ‘๊ทผ ๋ฐฉ๋ฒ•์€ MySQL ์„œ๋ฒ„์˜ ์ „๋ฌธ ๊ฒ€์ƒ‰(Full-text Search) ์ธ๋ฑ์Šค๋ฅผ ์‚ฌ์šฉํ•ด ๋ ˆ์ฝ”๋“œ ์ ‘๊ทผ
  • ์ „๋ฌธ ๊ฒ€์ƒ‰ ์ธ๋ฑ์Šค๋Š” ์ „ํ˜€ ๋‹ค๋ฅธ SQL ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค
    • MATCH (…) AGAINST (…) ๊ตฌ๋ฌธ??

5.6 ref_or_null

  • ref์—์„œ NULL ๋น„๊ต๋งŒ ์ถ”๊ฐ€๋œ ํ˜•ํƒœ
  • ๋งŽ์ด ํ™œ์šฉ๋˜์ง€๋Š” ์•Š์œผ๋‚˜ ์‚ฌ์šฉ๋œ๋‹ค๋ฉด ๋‚˜์˜์ง€ ์•Š์€ ์ •๋„์˜ ์ ‘๊ทผ ๋ฐฉ๋ฒ• ์ •๋„๋กœ ๊ธฐ์–ต

5.7 unique_subquery

  • WHERE ์กฐ๊ฑด์ ˆ์—์„œ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ๋Š” IN(Subquery) ํ˜•ํƒœ์˜ ์ฟผ๋ฆฌ๋ฅผ ์œ„ํ•œ ์ ‘๊ทผ ๋ฐฉ๋ฒ•
  • ์ด๋ฆ„ ๊ทธ๋Œ€๋กœ ์„œ๋ธŒ์ฟผ๋ฆฌ์—์„œ ์ค‘๋ณต๋˜์ง€ ์•Š๋Š” ์œ ๋‹ˆํฌํ•œ ๊ฐ’๋งŒ ๋ฐ˜ํ™˜ํ•  ๋•Œ ์‚ฌ์šฉ

๐Ÿ’ก type์ด unique_subquery์ด ์•„๋‹Œ๋ฐ์š”??

MySQL 8.0 ๋ฒ„์ „์—์„œ๋Š” ์œ„ ์ฟผ๋ฆฌ์ฒ˜๋Ÿผ WHERE ์กฐ๊ฑด์ ˆ์— ์‚ฌ์šฉ๋œ IN(Subquery) ํ˜•ํƒœ์˜ ์„ธ๋ฏธ ์กฐ์ธ์„ ์ตœ์ ํ™”ํ•˜๊ธฐ ์œ„ํ•ด ๋งŽ์€ ๊ธฐ๋Šฅ์ด ๋„์ž…๋˜์—ˆ๊ณ , ์ด๋กœ ์ธํ•ด ์ตœ์ ํ™”๋œ ์‹คํ–‰ ๊ณ„ํš์ด ๋ณด์ด๋Š” ๊ฒƒ semijoin ์ตœ์ ํ™” ์˜ต์…˜์„ on/off ํ•˜๋ฉด ์‹คํ–‰ ๊ณ„ํš์ด ๋‹ค๋ฅด๊ฒŒ ๋ณด์ž„

***
MySQL 5.6 ๋ฒ„์ „๊นŒ์ง€๋Š” employees ํ…Œ์ด๋ธ”์„ ์ฝ์–ด์„œ employees ํ…Œ์ด๋ธ”์˜ ๋ ˆ์ฝ”๋“œ๋งˆ๋‹ค salaries ํ…Œ์ด๋ธ”์„ ์ฝ๋Š” ์„œ๋ธŒ์ฟผ๋ฆฌ๊ฐ€ ์‹คํ–‰๋˜๋Š” ํ˜•ํƒœ๋กœ ์ฒ˜๋ฆฌ๋๋‹ค.

์œ„ 2.12 MATERIALIZED ์—์„œ ์–ธ๊ธ‰ํ–ˆ์—ˆ๋˜ ์„œ๋ธŒ์ฟผ๋ฆฌ ์ตœ์ ํ™”์˜ ์ฐจ์ด์ ์„ semijoin=on/off๋ฅผ ํ†ตํ•ด ์•„๋ž˜ ์‚ฌ์ง„์„ ํ†ตํ•ด ํŒŒ์•…ํ•ด๋ณด์ž.

semijoin=on/off ์‹œ ์‹คํ–‰ ๊ณ„ํš ์ฐจ์ด

  • MySQL 5.6 ๋ฒ„์ „๊นŒ์ง€๋Š” employees ํ…Œ์ด๋ธ”์„ ์ฝ์–ด์„œ employees ํ…Œ์ด๋ธ”์˜ ๋ ˆ์ฝ”๋“œ๋งˆ๋‹ค salaries ํ…Œ์ด๋ธ”์„ ์ฝ๋Š” ์„œ๋ธŒ์ฟผ๋ฆฌ๊ฐ€ ์‹คํ–‰๋˜๋Š” ํ˜•ํƒœ๋กœ ์ฒ˜๋ฆฌ๋๋‹ค. (Table Full Scan)
  • MySQL 5.7 ๋ฒ„์ „๋ถ€ํ„ฐ ์„œ๋ธŒ์ฟผ๋ฆฌ์˜ ๋‚ด์šฉ์„ ์ž„์‹œ ํ…Œ์ด๋ธ”๋กœ ๊ตฌ์ฒดํ™”(Materialization) ํ•œ ํ›„ ์ž„์‹œ ํ…Œ์ด๋ธ” ์‚ฌ์šฉ

5.8 index_subquery

  • IN(subquery)์—์„œ ์„œ๋ธŒ์ฟผ๋ฆฌ๊ฐ€ ์ค‘๋ณต๋œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, ์ด๋•Œ ์„œ๋ธŒ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ์˜ ์ค‘๋ณต๋œ ๊ฐ’์„ ์ธ๋ฑ์Šค๋ฅผ ์ด์šฉํ•ด์„œ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ์„ ๋•Œ index_subquery ์ ‘๊ทผ ๋ฐฉ๋ฒ• ์‚ฌ์šฉ
    • unqiue_subquery: ์„œ๋ธŒ์ฟผ๋ฆฌ ๋ฐ˜ํ™˜ ๊ฐ’์— ์ค‘๋ณต X
    • index_subquery: ์„œ๋ธŒ์ฟผ๋ฆฌ ๋ฐ˜ํ™˜ ๊ฐ’์— ์ค‘๋ณต์ด ์žˆ์„ ์ˆ˜ ์žˆ์œผ๋‚˜ index๋ฅผ ์ด์šฉํ•ด ์ค‘๋ณต ์ œ๊ฑฐ

5.9 range

  • ์ธ๋ฑ์Šค ๋ ˆ์ธ์ง€ ์Šค์บ” ํ˜•ํƒœ์˜ ์ ‘๊ทผ ๋ฐฉ๋ฒ•
  • range๋Š” ์ธ๋ฑ์Šค๋ฅผ ํ•˜๋‚˜์˜ ๊ฐ’์ด ์•„๋‹Œ ๋ฒ”์œ„๋กœ ๊ฒ€์ƒ‰ํ•˜๋Š” ๊ฒฝ์šฐ
  • ์ฃผ๋กœ “<, >, IS NULL, BETWEEN, IN, LIKE” ๋“ฑ์˜ ์—ฐ์‚ฐ์ž๋ฅผ ์ด์šฉํ•ด ์ธ๋ฑ์Šค ๊ฒ€์ƒ‰ํ•  ๋•Œ ์‚ฌ์šฉ
  • ์ผ๋ฐ˜์ ์œผ๋กœ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ฟผ๋ฆฌ๊ฐ€ ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋Š” ์ ‘๊ทผ ๋ฐฉ๋ฒ•
  • ์œ„์—์„œ ์†Œ๊ฐœํ•œ type ์นผ๋Ÿผ์—์„œ ์šฐ์„ ์ˆœ์œ„(์„ฑ๋Šฅ)๊ฐ€ ๋‚ฎ์œผ๋‚˜ range ์ ‘๊ทผ ๋ฐฉ๋ฒ•๋„ ์ƒ๋‹นํžˆ ๋น ๋ฆ„
  • ๋ชจ๋“  ์ฟผ๋ฆฌ๊ฐ€ ์ด ์ ‘๊ทผ ๋ฐฉ๋ฒ•๋งŒ ์‚ฌ์šฉํ•ด๋„ ์ตœ์ ์˜ ์„ฑ๋Šฅ์ด ๋ณด์žฅ๋œ๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ์Œ

5.11 index

  • index ์ ‘๊ทผ ๋ฐฉ๋ฒ•์€ ๋งŽ์€ ์‚ฌ๋žŒ์ด ์ž์ฃผ ์˜คํ•ดํ•˜๋Š” ์ ‘๊ทผ ๋ฐฉ๋ฒ•์œผ๋กœ ๋ฐ˜๋“œ์‹œ ํšจ์œจ์ ์ด์ง€๋Š” ์•Š์Œ
  • ์ธ๋ฑ์Šค๋ฅผ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋๊นŒ์ง€ ์ฝ๋Š” ์ธ๋ฑ์Šค ํ’€ ์Šค์บ”์„ ์˜๋ฏธํ•จ
  • ์ธ๋ฑ์Šค๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ๋ฐ์ดํ„ฐ ํŒŒ์ผ ์ „์ฒด๋ณด๋‹ค ํฌ๊ธฐ๊ฐ€ ์ž‘์œผ๋ฏ€๋กœ ์ธ๋ฑ์Šค ํ’€ ์Šค์บ”์‹œ ํ’€ ํ…Œ์ด๋ธ” ์Šค์บ”๋ณด๋‹ค ๋น ๋ฅด๊ฒŒ ์ฒ˜๋ฆฌ๋˜๋ฉฐ, ์ฟผ๋ฆฌ์˜ ๋‚ด์šฉ์— ๋”ฐ๋ผ ์ •๋ ฌ๋œ ์ธ๋ฑ์Šค์˜ ์žฅ์ ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ธฐ์— ํšจ์œจ์ ์ด๋ผ ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๋‹ค์Œ ์กฐ๊ฑด ์ค‘ (1,2) ์ถฉ์กฑ ํ˜น์€ (1,3) ์กฐ๊ฑด์„ ์ถฉ์กฑํ•˜๋Š” ์ฟผ๋ฆฌ์—์„œ ์‚ฌ์šฉ๋˜๋Š” ์ฝ๊ธฐ ๋ฐฉ์‹
    1. range๋‚˜ const, ref ๊ฐ™์€ ์ ‘๊ทผ ๋ฐฉ๋ฒ•์œผ๋กœ ์ธ๋ฑ์Šค๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ๋ชปํ•˜๋Š” ๊ฒฝ์šฐ
    2. ์ธ๋ฑ์Šค์— ํฌํ•จ๋œ ์นผ๋Ÿผ๋งŒ์œผ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ์ฟผ๋ฆฌ์ธ ๊ฒฝ์šฐ(ํ…Œ์ด๋ธ” ํ’€ ์Šค์บ”์„ ์•ˆํ•ด๋„ ๋˜๋Š” ๊ฒฝ์šฐ)
    3. ์ธ๋ฑ์Šค๋ฅผ ์ด์šฉํ•ด ์ •๋ ฌ์ด๋‚˜ ๊ทธ๋ฃจํ•‘ ์ž‘์—…์ด ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ(๋ณ„๋„ ์ •๋ ฌ ์ž‘์—…์„ ํ”ผํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ)

 

5.12 ALL

  • ํ’€ ํ…Œ์ด๋ธ” ์Šค์บ”์„ ์˜๋ฏธํ•˜๋Š” ์ ‘๊ทผ ๋ฐฉ๋ฒ•
  • ํ…Œ์ด๋ธ”์„ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋๊นŒ์ง€ ์ „๋ถ€ ์ฝ์–ด์„œ ๋ถˆํ•„์š”ํ•œ ๋ ˆ์ฝ”๋“œ๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  ๋ฐ˜ํ™˜
  • ์•ž์„  ๋ฐฉ์‹์œผ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์—†์„ ๋•Œ ๊ฐ€์žฅ ๋งˆ์ง€๋ง‰์— ์„ ํƒํ•˜๋Š” ๊ฐ€์žฅ ๋น„ํšจ์œจ์ ์ธ ๋ฐฉ๋ฒ•
  • ํ…Œ์ด๋ธ”์ด ๋งค์šฐ ์ž‘์ง€ ์•Š๋‹ค๋ฉด ์‹ค์ œ ํ…Œ์ด๋ธ”์— ๋ฐ์ดํ„ฐ๋ฅผ ์–ด๋Š ์ •๋„ ์ €์žฅํ•œ ์ƒํƒœ์—์„œ ์ฟผ๋ฆฌ์˜ ์„ฑ๋Šฅ์„ ํ™•์ธํ•ด๋ณด๊ณ  ์ ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

 

๐Ÿ”—  6. possible_keys

  • ์˜ตํ‹ฐ๋งˆ์ด์ €๊ฐ€ ์ตœ์ ์˜ ์‹คํ–‰ ๊ณ„ํš์„ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ํ›„๋ณด๋กœ ์„ ์ •ํ–ˆ๋˜ ์ ‘๊ทผ ๋ฐฉ๋ฒ•์—์„œ ์‚ฌ์šฉ๋˜๋Š” ์ธ๋ฑ์Šค์˜ ๋ชฉ๋ก
  • “์‚ฌ์šฉ๋  ๋ฒ•ํ–ˆ๋˜ ์ธ๋ฑ์Šค์˜ ๋ชฉ๋ก”์ด๋ฉฐ ๋ฐ˜๋“œ์‹œ ์‚ฌ์šฉ๋œ ๊ฒƒ์€ ์•„๋‹˜
  • ์‹คํ–‰ ๊ณ„ํš์—์„œ ํŠน๋ณ„ํ•œ ๊ฒฝ์šฐ๋ฅผ ์ œ์™ธํ•˜๊ณ ๋Š” ๊ทธ๋ƒฅ ๋ฌด์‹œํ•˜์ž.

 

๐Ÿ”—  7. key

  • key ์นผ๋Ÿผ์— ํ‘œ์‹œ๋˜๋Š” ์ธ๋ฑ์Šค๋Š” ์ตœ์ข… ์„ ํƒ๋œ ์‹คํ–‰ ๊ณ„ํš์—์„œ ์‚ฌ์šฉ๋˜๋Š” ์ธ๋ฑ์Šค
  • ์ฟผ๋ฆฌ ํŠœ๋‹ ์‹œ key ์นผ๋Ÿผ์— ์˜๋„ํ–ˆ๋˜ ์ธ๋ฑ์Šค๊ฐ€ ํ‘œ์‹œ๋˜๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•จ
  • ์‹คํ–‰ ๊ณ„ํš์˜ type์ด ALL์ผ ๋•Œ์™€ ๊ฐ™์ด ์ธ๋ฑ์Šค๋ฅผ ์ „ํ˜€ ์‚ฌ์šฉํ•˜์ง€ ๋ชปํ•˜๋ฉด NULL๋กœ ํ‘œ์‹œ๋จ

 

 

๐Ÿ”— 8. key_len ์นผ๋Ÿผ

  • ์„ ํƒ๋œ ์ธ๋ฑ์Šค์˜ ๊ธธ์ด๋ฅผ ํ‘œ์‹œ
  • ์ฟผ๋ฆฌ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ๋‹ค์ค‘ ์นผ๋Ÿผ์œผ๋กœ ๊ตฌ์„ฑ๋œ ์ธ๋ฑ์Šค์—์„œ ๋ช‡ ๊ฐœ์˜ ์นผ๋Ÿผ๊นŒ์ง€ ์‚ฌ์šฉํ–ˆ๋Š”์ง€ ํ‘œ๊ธฐ
  • ๋” ์ •ํ™•ํ•˜๊ฒŒ๋Š” ์ธ๋ฑ์Šค์˜ ๊ฐ ๋ ˆ์ฝ”๋“œ์—์„œ ๋ช‡ ๋ฐ”์ดํŠธ๊นŒ์ง€ ์‚ฌ์šฉํ–ˆ๋Š”์ง€ ์•Œ๋ ค์ฃผ๋Š” ๊ฐ’

INTEGER ํƒ€์ž…์€ 4๋ฐ”์ดํŠธ ์ฐจ์ง€

 

2 * INTEGER(4 Byte)

 

๐Ÿ”—  9. ref

  • ์ ‘๊ทผ ๋ฐฉ๋ฒ•์ด ref๋ฉด ์ฐธ์กฐ ์กฐ๊ฑด(equal ๋น„๊ต ์กฐ๊ฑด)์œผ๋กœ ์–ด๋–ค ๊ฐ’์ด ์ œ๊ณต๋๋Š”์ง€ ํ‘œ์‹œ
    • ์ƒ์ˆซ๊ฐ’ → const, ๋‹ค๋ฅธ ํ…Œ์ด๋ธ”์˜ ์นผ๋Ÿผ๊ฐ’์ด๋ฉด ๊ทธ ํ…Œ์ด๋ณ„๋ช…๊ณผ ์นผ๋Ÿผ๋ช…์ด ํ‘œ์‹œ
    • ์กฐ์ธ ์นผ๋Ÿผ์˜ ํƒ€์ž…(NUMBER, VARCHAR ๋“ฑ)์€ ๋™์ผํ•˜๊ฒŒ ์ผ์น˜์‹œํ‚ค๋Š” ํŽธ์ด ์ข‹๋‹ค.
  • ํฌ๊ฒŒ ์‹ ๊ฒฝ ์“ฐ์ง€ ์•Š์•„๋„ ๋ฌด๋ฐฉํ•จ

 

๐Ÿ”—  10. rows

  • ์‹คํ–‰ ๊ณ„ํš์˜ ํšจ์œจ์„ฑ ํŒ๋‹จ์„ ์œ„ํ•ด ์˜ˆ์ธกํ–ˆ๋˜ ๋ ˆ์ฝ”๋“œ ๊ฑด์ˆ˜๋ฅผ ๋ณด์—ฌ์ค€๋‹ค.
  • ์ฟผ๋ฆฌ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ์–ผ๋งˆ๋‚˜ ๋งŽ์€ ๋ ˆ์ฝ”๋“œ๋ฅผ ์ฝ๊ณ  ์ฒดํฌํ•ด์•ผ ํ•˜๋Š”์ง€๋ฅผ ์˜๋ฏธํ•จ
  • ํ†ต๊ณ„ ๊ฐ’์œผ๋กœ ๊ณ„์‚ฐํ•œ ๊ฐ’์ด๋ฏ€๋กœ ์‹ค์ œ ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ ๋ฐ˜ํ™˜๋œ ๋ ˆ์ฝ”๋“œ ๊ฑด์ˆ˜๋Š” ์ผ์น˜ํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Œ

 

๐Ÿ”—  11. filtered

  • ํ•„ํ„ฐ๋ง๋˜๊ณ  ๋‚จ์€ ๋ ˆ์ฝ”๋“œ์˜ ๋น„์œจ
  • ํ†ต๊ณ„ ๊ฐ’ ๋ฐ”ํƒ•์œผ๋กœ ๊ณ„์‚ฐํ•œ ๊ฐ’์œผ๋กœ ์‹ค์ œ ๊ฒฐ๊ณผ ๊ฐ’๊ณผ ๋ฐ˜๋“œ์‹œ ์ผ์น˜ํ•˜์ง€ ์•Š๋Š”๋‹ค.

row๊ฐ€ 5๊ฑด, filtered๊ฐ€ 100.00์ด๋ฉด ํ•„ํ„ฐ๋ง๋˜๊ณ  ๋‚จ์€ ๋ ˆ์ฝ”๋“œ๋Š” 5๊ฑด

 

row๊ฐ€ 4๊ฑด, filtered๊ฐ€ 33.33์ด๋ฉด ํ•„ํ„ฐ๋ง ๋˜๊ณ  ๋‚จ์€ ๋ ˆ์ฝ”๋“œ๋Š” 1.333๊ฑด (์ •ํ™•ํ•˜์ง€๋Š” ์•Š์Œ)

 

๐Ÿ”—  12. Extra

  • ์ฟผ๋ฆฌ ์‹คํ–‰ ๊ณ„ํš์—์„œ ์„ฑ๋Šฅ์— ๊ด€๋ จ๋œ ์ค‘์š”ํ•œ ๋‚ด์šฉ์ด Extra ์นผ๋Ÿผ์— ์ž์ฃผ ํ‘œ์‹œ๋จ
  • ๋‚ด๋ถ€์ ์ธ ์ฒ˜๋ฆฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜์— ๋Œ€ํ•ด ์กฐ๊ธˆ ๋” ๊นŠ์ด์žˆ๋Š” ๋‚ด์šฉ์„ ๋ณด์—ฌ์ฃผ๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Œ
  • ์˜ตํ‹ฐ๋งˆ์ด์ €๊ฐ€ ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๋Š”์ง€์— ๋Œ€ํ•ด ์•Œ๋ ค์ฃผ๋Š” ํžŒํŠธ ๊ฐ’

12.1 Using filesort

  • ORDER BY ์ฒ˜๋ฆฌ๊ฐ€ ์ธ๋ฑ์Šค๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ๋ชปํ•  ๋•Œ ์‹คํ–‰ ๊ณ„ํš์˜ Extra ์นผ๋Ÿผ์— “Using filesort” ํ‘œ์‹œ
  • ์ด๋Š” ์กฐํšŒ๋œ ๋ ˆ์ฝ”๋“œ๋ฅผ ์ •๋ ฌ์šฉ ๋ฉ”๋ชจ๋ฆฌ ๋ฒ„ํผ์— ๋ณต์‚ฌํ•ด ํ€ต ์†ŒํŠธ ๋˜๋Š” ํž™ ์†ŒํŠธ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ด์šฉํ•ด ์ •๋ ฌ ์ˆ˜ํ–‰
  • ORDER BY๊ฐ€ ์‚ฌ์šฉ๋œ ์ฟผ๋ฆฌ์˜ ์‹คํ–‰ ๊ณ„ํš์—์„œ๋งŒ ๋‚˜ํƒ€๋‚  ์ˆ˜ ์žˆ์Œ
  • Using filesort๊ฐ€ ์ถœ๋ ฅ๋˜๋Š” ์ฟผ๋ฆฌ๋Š” ๋งŽ์€ ๋ถ€ํ•˜๋ฅผ ์ผ์œผํ‚ค๋ฏ€๋กœ ๊ฐ€๋Šฅํ•˜๋‹ค๋ฉด ์ฟผ๋ฆฌ๋ฅผ ํŠœ๋‹ํ•˜๊ฑฐ๋‚˜ ์ธ๋ฑ์Šค๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Œ

12.2 Using index(์ปค๋ฒ„๋ง ์ธ๋ฑ์Šค)

๋ฐ์ดํ„ฐ ํŒŒ์ผ์„ ์ „ํ˜€ ์ฝ์ง€ ์•Š๊ณ  ์ธ๋ฑ์Šค๋งŒ ์ฝ์–ด์„œ ์ฟผ๋ฆฌ๋ฅผ ๋ชจ๋‘ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ ํ‘œ์‹œ

์ตœ์•…์˜ ๊ฒฝ์šฐ ์ธ๋ฑ์Šค๋ฅผ ํ†ตํ•ด ๊ฒ€์ƒ‰๋œ ๊ฒฐ๊ณผ ๋ ˆ์ฝ”๋“œ ํ•œ ๊ฑด์”ฉ ๋””์Šคํฌ๋ฅผ ์ฝ์–ด์•ผ ํ•  ์ˆ˜ ์žˆ๋‹ค.

์œ„ ์ฟผ๋ฆฌ๊ฐ€ ๋งŒ์•ฝ ์ธ๋ฑ์Šค(ix_firstname)๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด employees ํ…Œ์ด๋ธ”์˜ first_name ์นผ๋Ÿผ์— ์ƒ์„ฑ๋œ ์ธ๋ฑ์Šค๋ฅผ ์ด์šฉํ•ด ์ผ์น˜ํ•˜๋Š” ๋ ˆ์ฝ”๋“œ ๊ฑด์ˆ˜๋ฅผ ๊ฒ€์ƒ‰ํ•˜๊ณ , ๊ฐ ๋ ˆ์ฝ”๋“œ์˜ birth_date ์นผ๋Ÿผ์˜ ๊ฐ’์„ ์ฝ๊ธฐ ์œ„ํ•ด ๊ทธ ๋งŒํผ ์ถ”๊ฐ€์ ์œผ๋กœ ๋ฐ์ดํ„ฐ ํŽ˜์ด์ง€๋ฅผ ์ฝ์–ด์•ผ ํ•œ๋‹ค.

๊ทธ๋ž˜์„œ MySQL ์˜ตํ‹ฐ๋งˆ์ด์ €๋Š” ์ธ๋ฑ์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ํ’€ ํ…Œ์ด๋ธ” ์Šค์บ”์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” ํŽธ์ด ๋” ํšจ์œจ์ ์ด๋ผ๊ณ  ํŒ๋‹จํ•œ ๊ฒƒ์ด๋‹ค.

 

ํ•˜์ง€๋งŒ ์œ„ ์ฟผ๋ฆฌ์ฒ˜๋Ÿผ SELECT ์กฐํšŒ ์นผ๋Ÿผ์— birth_date ์นผ๋Ÿผ์„ ์ œ์™ธํ•˜๋ฉด ํ’€ ํ…Œ์ด๋ธ” ์Šค์บ”์ด ์•„๋‹Œ ์ธ๋ฑ์Šค ๋ ˆ์ธ์ง€ ์Šค์บ”์œผ๋กœ ์ฒ˜๋ฆฌ๊ฐ€ ๋œ๋‹ค.

์œ„ ์ฟผ๋ฆฌ๋Š” ์ธ๋ฑ์Šค๋ฅผ ํ†ตํ•ด ํ•„์š”ํ•œ ๋ ˆ์ฝ”๋“œ๋ฅผ ๊ฒ€์ƒ‰ํ•˜๊ณ  ํ•„์š”ํ•œ ์นผ๋Ÿผ(first_name)๊นŒ์ง€ ์ธ๋ฑ์Šค์—์„œ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋‹ค. ํ•„์š”ํ•œ ์นผ๋Ÿผ์ด ๋ชจ๋‘ ์ธ๋ฑ์Šค์— ์žˆ์œผ๋ฏ€๋กœ ๋งค์šฐ ๋น ๋ฅธ ์†๋„๋กœ ์ฒ˜๋ฆฌ๋œ๋‹ค.

 

์œ„์™€ ๊ฐ™์ด ์ธ๋ฑ์Šค๋งŒ์œผ๋กœ ์ฟผ๋ฆฌ ์ˆ˜ํ–‰์ด ๊ฐ€๋Šฅํ•  ๋•Œ ์‹คํ–‰ ๊ณ„ํš์˜ Extra์—๋Š” "Using index"๋ผ๋Š” ๋ฉ”์‹œ์ง€๊ฐ€ ์ถœ๋ ฅ๋˜๊ณ , ์ด๋ ‡๊ฒŒ ์ธ๋ฑ์Šค๋งŒ์œผ๋กœ ์ฒ˜๋ฆฌ๋˜๋Š” ๋ฐฉ๋ฒ•์„ "์ปค๋ฒ„๋ง ์ธ๋ฑ์Šค(Covering Index)"๋ผ๊ณ  ํ•œ๋‹ค.

 

์ธ๋ฑ์Šค ๋ ˆ์ธ์ง€ ์Šค์บ”์„ ์‚ฌ์šฉํ•˜์ง€๋งŒ ์ฟผ๋ฆฌ์˜ ์„ฑ๋Šฅ์ด ๋งŒ์กฑ์Šค๋Ÿฝ์ง€ ๋ชปํ•œ ๊ฒฝ์šฐ ์œ„ ๋‘ ๋ฒˆ์งธ ์˜ˆ์ œ์ฒ˜๋Ÿผ ์ธ๋ฑ์Šค์— ์žˆ๋Š” ์นผ๋Ÿผ๋งŒ ์‚ฌ์šฉํ•˜๋„๋ก ์ฟผ๋ฆฌ๋ฅผ ๋ณ€๊ฒฝํ•˜์—ฌ ํฐ ์„ฑ๋Šฅ ํ–ฅ์ƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

(์ฟผ๋ฆฌ๋ฅผ ์ปค๋ฒ„๋ง ์ธ๋ฑ์Šค๋กœ ์ฒ˜๋ฆฌํ•˜๋Š๋ƒ ๋ชปํ•˜๋Š๋ƒ์˜ ์„ฑ๋Šฅ ์ฐจ์ด๋Š” ์ˆ˜์‹ญ ๋ฐฐ์—์„œ ์ˆ˜๋ฐฑ ๋ฐฐ๊นŒ์ง€ ๋‚  ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ•œ๋‹ค.)

 

12.3 Using temporary

์ฟผ๋ฆฌ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋™์•ˆ ์ค‘๊ฐ„ ๊ฒฐ๊ณผ๋ฅผ ๋‹ด์•„ ๋‘๊ธฐ ์œ„ํ•ด ์ž„์‹œ ํ…Œ์ด๋ธ”(Temporary Table)์„ ์ƒ์„ฑํ•˜์—ฌ ํ‘œ์‹œ๋œ ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค.

12.4 Using index for skip scan

MySQL ์˜ตํ‹ฐ๋งˆ์ด์ €๊ฐ€ ์ธ๋ฑ์Šค ์Šคํ‚ต ์Šค์บ” ์ตœ์ ํ™”๋ฅผ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ "Using index for skip scan"

๐Ÿ’ก index skip scan 

์˜ˆ๋ฅผ ๋“ค์–ด, employees ํ…Œ์ด๋ธ”์—์„œ (gender, birth_date) ์นผ๋Ÿผ์œผ๋กœ ์ด๋ฃจ์–ด์ง„ ix_gb ์ธ๋ฑ์Šค๊ฐ€ ์กด์žฌํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณด์ž.
MySQL 8.0 ๋ฒ„์ „ ๋ถ€ํ„ฐ WHERE ์กฐ๊ฑด์ ˆ์— ์ธ๋ฑ์Šค์˜ ์„ ํ–‰ ์นผ๋Ÿผ์ธ gender ์กฐ๊ฑด์ด ์—†์ด birth_date ์นผ๋Ÿผ์œผ๋กœ๋งŒ ์ด๋ฃจ์–ด์ง„ ์ฟผ๋ฆฌ๊ฐ€ ์กด์žฌํ•˜๋”๋ผ๋„ ์ธ๋ฑ์Šค๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค€๋‹ค.

// ๊ธฐ์กด์—๋Š” ์ธ๋ฑ์Šค๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Œ
SELECT * FROM employees WHERE birth_date >= '2001-02-04';

// skip scan์€ ๋Œ€๋žต์ ์œผ๋กœ ์•„๋ž˜์™€ ๊ฐ™์ด ์ฟผ๋ฆฌ๊ฐ€ ์ฒ˜๋ฆฌ๋จ
SELECT * FROM employees WHERE gender = 'M' AND birth_date >= '2001-02-04';
SELECT * FROM employees WHERE gender = 'F' AND birth_date >= '2001-02-04';

* ํ•˜์ง€๋งŒ WHERE ์กฐ๊ฑด์ ˆ์— ์—†๋Š” gender ์นผ๋Ÿผ์˜ ์œ ๋‹ˆํฌํ•œ ๊ฐ’์˜ ๊ฐœ์ˆ˜๊ฐ€ ์ ์–ด์•ผ ํ•œ๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ๋‹ค.
(์œ„์—์„œ๋Š” 'M', 'F' 2๊ฐœ๋งŒ ์กด์žฌ)

12.5 Using join buffer(Block Nested Loop, hash join)

๋ณดํ†ต ๋น ๋ฅธ ์ฟผ๋ฆฌ ์‹คํ–‰์„ ์œ„ํ•ด ์กฐ์ธ๋˜๋Š” ์นผ๋Ÿผ์—๋Š” ์ธ๋ฑ์Šค๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

์‹ค์ œ ์กฐ์ธ์— ํ•„์š”ํ•œ ์ธ๋ฑ์Šค๋Š” ์กฐ์ธ์—์„œ ๋’ค์— ์ฝ๋Š” ํ…Œ์ด๋ธ”(๋“œ๋ฆฌ๋ธ ํ…Œ์ด๋ธ”)์˜ ์นผ๋Ÿผ์—๋งŒ ํ•„์š”ํ•˜๋‹ค. 

(๋’ค์— ์ฝ๋Š” ํ…Œ์ด๋ธ”์€ ๊ฒ€์ƒ‰ ์œ„์ฃผ๋กœ ์‚ฌ์šฉ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ธ๋ฑ์Šค๊ฐ€ ์—†์œผ๋ฉด ์„ฑ๋Šฅ์— ๋ฏธ์น˜๋Š” ์˜ํ–ฅ์ด ํฌ๊ธฐ ๋•Œ๋ฌธ)

 

์ด์ฒ˜๋Ÿผ ์กฐ์ธ์ด ์ˆ˜ํ–‰๋  ๋•Œ ๋“œ๋ฆฌ๋ธ ํ…Œ์ด๋ธ”์— ์ ์ ˆํ•œ ์ธ๋ฑ์Šค๊ฐ€ ์—†๋‹ค๋ฉด, MySQL ์˜ตํ‹ฐ๋งˆ์ด์ €๋Š” ๋ธ”๋ก ๋„ค์Šคํ‹ฐ๋“œ ๋ฃจํ”„๋‚˜ ํ•ด์‹œ ์กฐ์ธ์„ ์‚ฌ์šฉํ•œ๋‹ค.

์ด๋Š” MySQL ์„œ๋ฒ„์˜ join buffer๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. (join_buffer_size๋ผ๋Š” ์‹œ์Šคํ…œ ๋ณ€์ˆ˜๋ฅผ ํ†ตํ•ด ์กฐ์ธ ๋ฒ„ํผ์˜ ํฌ๊ธฐ ์„ค์ •์ด ๊ฐ€๋Šฅํ•˜๋‹ค.)

12.6 Using where

์ฟผ๋ฆฌ์— ๋Œ€ํ•œ ์ ‘๊ทผ ๋ฐฉ์‹์„ ์„ค๋ช…ํ•œ ๊ฒƒ์œผ๋กœ ์Šคํ† ๋ฆฌ์ง€ ์—”์ง„์œผ๋กœ ๋ถ€ํ„ฐ ๋ฐ›์€ ๋ฐ์ดํ„ฐ๋ฅผ MySQL ์—”์ง„์—์„œ ๋ณ„๋„์˜ ๊ฐ€๊ณต์„ ํ•ด์„œ ํ•„ํ„ฐ๋ง ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•œ ๊ฒฝ์šฐ Extra ์นผ๋Ÿผ์— "Using where" ํ‘œ์‹œ

 

 

์˜ˆ์ œ๋กœ ์‚ฌ์šฉ๋œ ์ฟผ๋ฆฌ

๋”๋ณด๊ธฐ

-- EXPLAIN
-- SELECT * 
-- FROM employees e 
-- INNER JOIN salaries s ON e.emp_no = s.emp_no
-- WHERE first_name = 'ABC';

-- id, SIMPLE
EXPLAIN 
SELECT e.*
FROM employees e, salaries s
WHERE e.emp_no = s.emp_no;

EXPLAIN 
SELECT e.*
FROM employees e
INNER JOIN salaries s ON s.emp_no = e.emp_no;


-- id, PRIMARY
EXPLAIN
SELECT 
( (SELECT COUNT(*) FROM employees) + (SELECT COUNT(*) FROM salaries) ) AS total_count
FROM employees;
    
-- Subquery
EXPLAIN
SELECT 
e.first_name, 
    (SELECT COUNT(*) FROM salaries LIMIT 3) AS cnt
FROM employees e
WHERE e.emp_no = 3;    

-- Union
EXPLAIN
SELECT *
FROM (
(SELECT emp_no FROM employees e1 LIMIT 2) UNION ALL
    (SELECT emp_no FROM employees e2 LIMIT 2) UNION ALL
    (SELECT emp_no FROM employees e3 LIMIT 3)
) tb;

-- Dependent Union
EXPLAIN
SELECT *
FROM employees e1 
WHERE e1.emp_no IN (
SELECT e2.emp_no FROM employees e2 WHERE e2.first_name = 'Matt'
    UNION
    SELECT e3.emp_no FROM employees e3 WHERE e3.last_name = 'Matt'
);

-- Subquery
EXPLAIN
SELECT 
e.first_name, 
    (SELECT COUNT(*) FROM salaries LIMIT 3) AS cnt
FROM employees e
WHERE e.emp_no = 3;

-- Derived
EXPLAIN
SELECT *
FROM ( SELECT s.emp_no FROM salaries s GROUP BY s.emp_no) tb,
employees e
WHERE e.emp_no = tb.emp_no;

-- Derived join
EXPLAIN 
SELECT *
FROM employees e
JOIN (SELECT s.emp_no FROM salaries s GROUP BY s.emp_no) tb
ON e.emp_no = tb.emp_no;

-- Materialized
EXPLAIN
SELECT *
FROM employees e
WHERE e.emp_no IN (
SELECT  emp_no FROM salaries WHERE amount BETWEEN 100 AND 1000
);

EXPLAIN
SELECT NOW();



SELECT *
FROM ( SELECT s.emp_no FROM salaries s GROUP BY s.emp_no) tb,
employees e
WHERE tb.emp_no = e.emp_no;

SELECT * FROM employees e
WHERE e.emp_no IN ( 
SELECT emp_no FROM salaries WHERE amount BETWEEN 12000 AND 16000
);

SELECT * FROM salaries;

CREATE TABLE employees_partitions(
emp_no int NOT NULL AUTO_INCREMENT,
    birth_date DATE NOT NULL,
    first_name VARCHAR(16) NOT NULL,
    last_name VARCHAR(16) NOT NULL,
    hire_date DATE NOT NULL,
    PRIMARY KEY (emp_no, hire_date)
) PARTITION BY RANGE COLUMNS(hire_date)
(
    PARTITION p2000 VALUES LESS THAN ('2000-01-01'),
    PARTITION p2005 VALUES LESS THAN ('2005-01-01'),
    PARTITION p2010 VALUES LESS THAN ('2010-01-01'),
    PARTITION p2015 VALUES LESS THAN ('2015-01-01'),
    PARTITION p2020 VALUES LESS THAN ('2020-01-01')
);

INSERT INTO employees_partitions VALUES (null, "2022-12-30", 'JH', 'Lee', '2019-12-30');
INSERT INTO employees_partitions VALUES (null, "2022-11-30", 'JH', 'Lee', '2019-12-30');
INSERT INTO employees_partitions VALUES (null, "2022-10-30", 'JH', 'Lee', '2019-12-30');
INSERT INTO employees_partitions VALUES (null, "2022-09-30", 'JH', 'Lee', '2019-12-30');
INSERT INTO employees_partitions VALUES (null, "2022-08-30", 'JH', 'Lee', '2019-12-30');

SELECT * FROM employees_partitions;

-- partitions
EXPLAIN
SELECT *
FROM employees_partitions
WHERE hire_date BETWEEN '2014-01-06' AND '2022-12-30';



-- MyISAM -> system
CREATE TABLE employees_2(
emp_no int NOT NULL AUTO_INCREMENT PRIMARY KEY,
    birth_date DATE NOT NULL,
    first_name VARCHAR(16) NOT NULL,
    last_name VARCHAR(16) NOT NULL
) ENGINE = MyISAM;

INSERT INTO employees_2 VALUES (null, '2022-12-30', 'a', 'b');
commit;
EXPLAIN SELECT * FROM employees_2;

-- InnoDB -> ALL
CREATE TABLE employees_3(
emp_no int NOT NULL AUTO_INCREMENT PRIMARY KEY,
    birth_date DATE NOT NULL,
    first_name VARCHAR(16) NOT NULL,
    last_name VARCHAR(16) NOT NULL
) ENGINE = InnoDB;

INSERT INTO employees_3 VALUES (null, '2022-12-30', 'a', 'b');
commit;
EXPLAIN SELECT * FROM employees_3;

SELECT * FROM employees;

-- const
EXPLAIN SELECT * FROM employees WHERE emp_no = 4 AND hire_date = '2000-01-01';
EXPLAIN SELECT * FROM salaries WHERE sal_id = 2;

EXPLAIN
SELECT *
FROM employees e, salaries s
WHERE e.emp_no = s.emp_no
AND s.sal_id = 2;
    
-- ref
EXPLAIN
SELECT * FROM employees e WHERE e.emp_no = 3;

-- ALL
EXPLAIN
SELECT * FROM salaries s WHERE s.emp_no = 3;

-- const
EXPLAIN
SELECT * FROM salaries s WHERE s.sal_id = 2;

SELECT * FROM salaries;
INSERT INTO salaries VALUES (6, null, 8000);

-- unique_subquery
EXPLAIN
SELECT * FROM employees
WHERE emp_no IN (
SELECT emp_no FROM salaries WHERE sal_id = 3
);

-- const, ref (MySQL ๋ฒ„์ „ 5.x -> unqiue_subquery)
EXPLAIN
SELECT * FROM employees
WHERE emp_no IN (
SELECT emp_no FROM salaries WHERE sal_id = 3
);

-- range
EXPLAIN
SELECT * FROM employees
WHERE emp_no BETWEEN 2 AND 6;

-- range
EXPLAIN
SELECT * FROM salaries
WHERE amount BETWEEN 9000 AND 14000;

SELECT * FROM employees;
SELECT * FROM salaries;

EXPLAIN
SELECT * FROM employees ORDER BY last_name LIMIT 5;

EXPLAIN
SELECT * FROM employees ORDER BY emp_no LIMIT 5;

EXPLAIN
SELECT * FROM employees ORDER BY hire_date LIMIT 5;

EXPLAIN
SELECT * FROM employees ORDER BY emp_no, hire_date LIMIT 5;

EXPLAIN
SELECT * FROM salaries ORDER BY sal_id;

EXPLAIN
SELECT * FROM salaries ORDER BY emp_no;

EXPLAIN
SELECT * FROM employees;

-- key_len
EXPLAIN
SELECT * FROM dept_emp WHERE dept_no = 1 AND emp_no = '3';
SELECT * FROM dept_emp;

-- ref 
SELECT *
FROM employees e, dept_emp de
WHERE e.emp_no = de.emp_no;

-- ์ด ๋ฐ์ดํ„ฐ: 450๋งŒ๊ฑด
EXPLAIN
SELECT * FROM salaries WHERE amount > 2000 AND sal_id > 10000;

EXPLAIN
SELECT * FROM salaries WHERE emp_no = 1;

EXPLAIN
SELECT * FROM dept_emp WHERE dept_no > 3;

-- 25๊ฑด ์ค‘ 10๊ฑด ์กฐํšŒ 
EXPLAIN
SELECT * FROM employees_partitions WHERE hire_date > '2014-12-01'; 

-- 5๊ฑด, 33.33
EXPLAIN
SELECT * FROM employees_partitions WHERE emp_no > 20 AND hire_date > '2014-12-01'; 

EXPLAIN
SELECT * FROM employees_partitions WHERE emp_no > 20;

-- 10
SELECT * FROM employees_partitions WHERE hire_date > '2014-12-01';


-- 5๊ฑด, row:5, filter: 100
EXPLAIN
SELECT * FROM employees_partitions WHERE emp_no > 20;

-- 2๊ฑด, row:4, filter:33.33
EXPLAIN
SELECT * FROM employees_partitions WHERE emp_no > 20 AND hire_date > '2019-12-01'; 

SELECT COUNT(*) FROM employees_partitions WHERE emp_no > 20;
SELECT COUNT(*) FROM employees_partitions WHERE emp_no > 20 AND hire_date > '2019-12-01';

EXPLAIN
SELECT * FROM salaries ORDER BY amount;


EXPLAIN 
SELECT e.*
FROM employees e, salaries s
WHERE e.emp_no = s.emp_no;


EXPLAIN 
SELECT e.*
FROM employees e
INNER JOIN salaries s ON e.emp_no = s.emp_no;


-- Derived
EXPLAIN
SELECT *
FROM (SELECT s.emp_no FROM salaries s GROUP BY s.emp_no) tb,
employees e
WHERE e.emp_no = tb.emp_no;

-- Join
EXPLAIN
SELECT *
FROM employees e
-- JOIN ์ ˆ์—์„œ ์„œ๋ธŒ์ฟผ๋ฆฌ ์‚ฌ์šฉ
JOIN (SELECT s.emp_no FROM salaries s GROUP BY s.emp_no) tb
ON e.emp_no = tb.emp_no;

EXPLAIN
SELECT *
FROM employees e
-- JOIN ์ ˆ์—์„œ ์„œ๋ธŒ์ฟผ๋ฆฌ ์‚ฌ์šฉ
JOIN (SELECT s.emp_no FROM salaries s GROUP BY s.emp_no) tb
ON e.emp_no = tb.emp_no;

EXPLAIN FORMAT=TREE
SELECT * 
FROM dept_emp de, employees e
WHERE e.emp_no = de.emp_no
AND de.dept_no = '1';
    
SELECT VERSION();

EXPLAIN
SELECT * FROM employees_partitions WHERE hire_date LIKE '2010%';


SELECT COUNT(*) FROM employees;
INSERT INTO employees VALUES (3, '2002-01-02', 'Hali', 'A', 'M', '2009-04-01', '2');

EXPLAIN 
SELECT first_name
FROM employees WHERE first_name BETWEEN 'Jade' AND 'Neo';

EXPLAIN 
SELECT first_name, birth_date
FROM employees WHERE first_name BETWEEN 'Jade' AND 'Neo';

EXPLAIN 
SELECT emp_no, first_name
FROM employees WHERE first_name BETWEEN 'Jade' AND 'Neo';

 

๐Ÿ“„ ์ฐธ๊ณ  ๋ฌธ์„œ

๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€