JiwonDev

์ •๋ฆฌ์ค‘-5

by JiwonDev

์šฐ๋ฆฌ๊ฐ€ ๊ด€๊ณ„ํ˜•DB๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด์„œ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๊ฒƒ์€ ์˜ตํ‹ฐ๋งˆ์ด์ €(SQL Optimizer)๊ฐ€ ์ฟผ๋ฆฌ๋ฅผ ์–ด๋–ป๊ฒŒ ์‹คํ–‰ํ•˜๋Š”์ง€์ด๋‹ค.

 

๋ฌผ๋ก  ์šฐ๋ฆฌ๊ฐ€ ์ž‘์„ฑํ•œ SQL๋ฌธ์„ ์‹คํ–‰๊ณ„ํš์œผ๋กœ ๋งŒ๋“œ๋Š”๊ฑด ์˜ตํ‹ฐ๋งˆ์ด์ €์˜ ์—ญํ• ์ด์ง€๋งŒ, ์šฐ๋ฆฌ๋Š” ์ตœ์ ์˜ ์‹คํ–‰ ๊ณ„ํš์ด ์‚ฌ์šฉ ๋  ์ˆ˜ ์žˆ๋„๋ก ์˜ตํ‹ฐ๋งˆ์ด์ €์—๊ฒŒ ํžŒํŠธ๋ฅผ ์ค„ ์ˆ˜ ์žˆ๋Š” ์ฟผ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•ด์•ผ ํ•œ๋‹ค.

 

๐Ÿ“Œ MySQL ์—”์ง„์—์„œ ์ฟผ๋ฆฌ๊ฐ€ ์‹คํ–‰๋˜๋Š” ๊ณผ์ •

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

 

๐Ÿ“Œ ์ตœ์ ํ™” ํ•œ๋‹ค๋Š” ๊ฒƒ์€

ํ’€ ํ…Œ์ด๋ธ” ์Šค์บ”์„ ์ตœ์†Œํ™”ํ•˜๊ณ  ๋งŒ๋“ค์–ด๋‘” ์ธ๋ฑ์Šค๋ฅผ ์ด์šฉํ•ด ๊ฐ’์„ ํ•œ๋ฒˆ์— ์ฐพ๋„๋ก ๋งŒ๋“ค์–ด์„œ ์„ฑ๋Šฅ์„ ๋Œ์–ด ์˜ฌ๋ฆฐ๋‹ค๋Š” ๋ง์ด๋‹ค.

 

๋‹ค๋งŒ ์•ž์žฅ์—์„œ ์ด์•ผ๊ธฐํ–ˆ์ง€๋งŒ, ์ธ๋ฑ์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๊ฒŒ ๋ฐ˜๋“œ์‹œ ๋น ๋ฅด๋‹ค๋Š” ๋ฒ•์€ ์—†๋‹ค. ์กฐํšŒ๋ฅผ ์ œ์™ธํ•œ ์‚ฝ์ž…/์‚ญ์ œ๋“ฑ์€ ์ธ๋ฑ์Šค์—๋„ ๊ฐ™์ด ๋ฐ˜์˜ํ•ด์ค˜์•ผ ํ•˜๊ธฐ์— ๋” ๋Š๋ ค์ง„๋‹ค.

 

๋˜ํ•œ ์กฐํšŒ๋ผ๊ณ  ํ•˜๋”๋ผ๋„ ์•„๋ž˜์™€ ๊ฐ™์€ ์ƒํ™ฉ์—์„œ๋Š” ์ „์ฒด ํ…Œ์ด๋ธ”์„ ์กฐํšŒํ•˜๋Š” ๊ฒฝ์šฐ ์ธ๋ฑ์Šค๋ฅผ ๊ฑฐ์น˜๋Š”๊ฒŒ ๋” ๋Š๋ฆด ์ˆ˜ ์žˆ๋‹ค.

  • ํ…Œ์ด๋ธ”์˜ ๋ ˆ์ฝ”๋“œ ๊ฑด์ˆ˜๊ฐ€ ๋„ˆ๋ฌด ์ž‘์•„์„œ ๊ทธ๋ƒฅ ํ’€ ํ…Œ์ด๋ธ” ์Šค์บ”์„ ํ•˜๋Š”๊ฒŒ ๋” ๋น ๋ฅธ ๊ฒฝ์šฐ (ํ…Œ์ด๋ธ” ํŽ˜์ด์ง€๊ฐ€ 1๊ฐœ์ธ ๊ฒฝ์šฐ)
  • Where ์ ˆ์ด๋‚˜ On ์ ˆ์— ์ด์šฉํ•  ๋งŒํ•œ๊ฒŒ ์—†์–ด์„œ ์ธ๋ฑ์Šค๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ
  • ์ธ๋ฑ์Šค ๋ ˆ์ธ์ง€ ์Šค์บ”์ด ๊ฐ€๋Šฅํ•˜๋‚˜, ์ผ์น˜ ๋ ˆ์ฝ”๋“œ ์ˆ˜๊ฐ€ ๋„ˆ๋ฌด ๋งŽ์€ ๊ฒฝ์šฐ (ํ†ต๊ณ„์ ์œผ๋กœ ์ „์ฒด ํ…Œ์ด๋ธ”์˜ 20% ์ด์ƒ)

 

๐Ÿ“Œ Optimizer์˜ ๋™์ž‘๋ฐฉ์‹

์ด์ „์—๋Š” ๋Œ€๋ถ€๋ถ„ ๊ทœ์น™ ๊ธฐ๋ฐ˜(Rule-Base)์˜ ์˜ตํ‹ฐ๋งˆ์ด์ € ์˜€์ง€๋งŒ, ์ตœ๊ทผ์—๋Š” ๋น„์šฉ ๊ธฐ๋ฐ˜(Cost-Base)์˜ ์˜ตํ‹ฐ๋งˆ์ด์ €๊ฐ€ ์‚ฌ์šฉ๋œ๋‹ค.

์ฆ‰ ์ฟผ๋ฆฌ ๋Œ€์ƒ์˜ ๋ ˆ์ฝ”๋“œ ์ˆ˜, ์„ ํƒ๋„ ๋“ฑ์˜ ํ†ต๊ณ„์ •๋ณด๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ์‹คํ–‰๊ณ„ํš์„ ์ƒ์„ฑํ•œ๋‹ค.

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

 

๋‹ค๋ฅธ ๋ง๋กœํ•˜๋ฉด ํ†ต๊ณ„ ์ •๋ณด๊ฐ€ ์ •ํ™•ํ•  ์ˆ˜๋ก ์ข‹์€ ์‹คํ–‰ ๊ณ„ํš์„ ๋งŒ๋“ค ํ™•๋ฅ ์ด ๋†’๋‹ค๋Š” ์ด์•ผ๊ธฐ.

ํŠน์ • ์ฟผ๋ฆฌ์˜ ์‹คํ–‰๊ณ„ํš์€ EXPLAIN ํ‚ค์›Œ๋“œ๋กœ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋Š” ํ†ต๊ณ„์ •๋ณด๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•œ ์‹คํ–‰๊ณ„ํš์„ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

mysql> SELECT count(*) FROM t1 JOIN t2 ON (t1.c1 = t2.c2);
+----------+
| count(*) |
+----------+
|  1953125 |
+----------+

mysql> EXPLAIN format=tree --mysql 8.0๋ถ€ํ„ฐ๋Š” ์˜ต์…˜์„ ์ฃผ๋ฉด Json์ด๋‚˜ Tree ํ˜•ํƒœ๋กœ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.
SELECT * FROM t1 JOIN t2 ON (t1.c1 = t2.c2)\G
*************************** 1. row ***************************
EXPLAIN: 
  -> Inner hash join (t2.c2 = t1.c1)  (cost=976879.74 rows=976563)
  -> Table scan on t2  (cost=0.01 rows=3125)
  -> Hash
      -> Table scan on t1  (cost=314.75 rows=3125)

 

MySQL ์—”์ง„๋Š” ํ†ต๊ณ„ ์ •๋ณด๋Š” ์ธ๋ฑ์Šค๋ฅผ ํ†ตํ•ด ์„œ๋น„์Šค์ค‘์—๋„ ๊ณ„์† ์ˆ˜์ง‘, ์ˆ˜์ •ํ•œ๋‹ค. ์ฐธ๊ณ ๋กœ MySQL 8.0๋ถ€ํ„ฐ๋Š” ์ธ๋ฑ์Šค๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์ผ๋ฐ˜ ์นผ๋Ÿผ์—๋„ ํ†ต๊ณ„ ์ •๋ณด(Histogram)์„ ์ˆ˜์ง‘ํ•œ๋‹ค. ์‹ค์ œ๋กœ innodb_stats_sample_pages ์„ค์ •๊ฐ’์„ ์ด์šฉํ•˜๋ฉด ํ†ต๊ณ„ ์ •๋ณด๋ฅผ ์œ„ํ•ด ๋ถ„์„ํ•  ์ธ๋ฑ์Šค ํŽ˜์ด์ง€ ๊ฐœ์ˆ˜๋ฅผ ์ง€์ •ํ•ด ์ค„ ์ˆ˜ ์žˆ๋‹ค.

 

๋‹น์—ฐํžˆ ๋ถ„์„ํ•  ํŽ˜์ด์ง€ ์ˆ˜๊ฐ€ ๋งŽ์œผ๋ฉด ์ •๋ณด๊ฐ€ ๋” ์ •ํ™•ํ•˜๊ฒ ์ง€๋งŒ, ์ˆ˜์ง‘ ์ค‘์—๋Š” ํ…Œ์ด๋ธ” ์ฝ๊ธฐ/์“ฐ๊ธฐ๊ฐ€ ๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ DB ์„ฑ๋Šฅ์— ํฐ ์˜ํ–ฅ์ด ๊ฐ„๋‹ค. ๊ทธ๋ž˜์„œ ์ด ๊ฐ’์€ ๋งŽ์•„๋„ 16~24 ํŽ˜์ด์ง€ ์ •๋„๋งŒ ์‚ฌ์šฉํ•˜๊ธฐ๋ฅผ ๊ถŒ์žฅํ•œ๋‹ค.

 

์ฐธ๊ณ ๋กœ MySQL 8.0.18์€ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์œผ๋กœ EXPLAIN ANALYZE๋ฅผ ์ œ๊ณตํ•œ๋‹ค. ํ•ด๋‹น ๊ธฐ๋Šฅ์€ ์‹ค์ œ ์ˆ˜ํ–‰ํ–ˆ์„ ๋•Œ( actual ) ์†Œ๋น„๋˜๋Š” ์‹œ๊ฐ„, ์—ฐ์‚ฐ๋ณ„ ์ฒ˜๋ฆฌ ๊ฑด ์ˆ˜, ์˜ˆ์ƒ ์‹คํ–‰๋น„์šฉ๋“ฑ์„ ํ•จ๊ป˜ ๋ณด์—ฌ์ค€๋‹ค.

mysql> EXPLAIN ANALYZE 
SELECT * FROM t1 JOIN t2 ON (t1.c1 = t2.c2)\G
*************************** 1. row ***************************
EXPLAIN: 
  -> Inner hash join (t2.c2 = t1.c1)  (cost=976879.74 rows=976563) (actual time=1.229..74.317 rows=1953125 loops=1)
  -> Table scan on t2  (cost=0.01 rows=3125) (actual time=0.006..2.386 rows=3125 loops=1)
  -> Hash
        -> Table scan on t1  (cost=314.75 rows=3125) (actual time=0.017..0.983 rows=3125 loops=1)

 

 

๐Ÿ“Œ ์‹คํ–‰๊ณ„ํš ๋ถ„์„ํ•˜๊ธฐ (Explain)

EXPLAIN <์ฟผ๋ฆฌ> ๋ฅผ ์ž…๋ ฅํ•˜๋ฉด ๊ธฐ๋ณธ์ ์œผ๋กœ ์•„๋ž˜์™€ ๊ฐ™์€ ์‹คํ–‰๊ณ„ํš ํ…Œ์ด๋ธ”์„ ์ œ๊ณตํ•ด์ค€๋‹ค.

๋‹ค๋งŒ ๊ตณ์ด ์™ธ์šธ๋ ค๊ณ  ํ•˜๊ธฐ๋ณด๋‹ค๋Š”, ์ž์ฃผ ๋ณด๋‹ค๋ณด๋ฉด ์–ด๋–ค๊ฒŒ ์ค‘์š”ํ•œ ๊ฐ’์ธ์ง€ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ์•Œ์•„๊ฐ€๋Š”๊ฑธ ๊ถŒ์žฅํ•œ๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด ์ธ๋ฑ์Šค ์‚ฌ์šฉ๋ฐฉ์‹์„ ๋‚˜ํƒ€๋‚ด๋Š” type๊ณผ ๋ถ€๊ฐ€์ •๋ณด๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” Extra๋Š” ์ค‘์š”ํ•˜์ง€๋งŒ
ํ›„๋ณด ์ธ๋ฑ์Šค ํ‚ค๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” possilbe_keys ๊ฐ™์€ ๊ฑด ๋ณ„ ์“ธ๋ชจ๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค ์™ธ์šฐ๋Š”๊ฑด ์“ธ๋ชจ ์—†๋Š” ์ง“์ด๋‹ค.

์ฐธ๊ณ ๋กœ mysql ์„œ๋ฒ„ ์ฝ˜์†”์— ๊ทธ๋ƒฅ EXPLAIN์„ ์ฐ์œผ๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ๋‚˜์˜จ๋‹ค.

UI๋งŒ ๋‹ค๋ฅผ ๋ฟ, ์ฝ˜์†”์—์„œ ํ…์ŠคํŠธ๋กœ ๋˜‘๊ฐ™์€ ์‹คํ–‰๊ณ„ํš ํ…Œ์ด๋ธ”์„ ์ œ๊ณตํ•ด์ค€๋‹ค.

๐Ÿ“Œ id (select_id) ์นผ๋Ÿผ

SELECT ํ•ญ๋ชฉ์„ ๊ตฌ๋ถ„ํ•˜๋Š” ๋ฒˆํ˜ธ, ์—ฌ๋Ÿฌ ํ…Œ์ด๋ธ”์„ ์กฐํšŒํ•˜๋”๋ผ๋„ Join์œผ๋กœ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋‹ค๋ฉด ๋‹ค๋ฅธ ๋™์ผํ•œ ID๊ฐ€ ๋ถ€์—ฌ๋œ๋‹ค.


๐Ÿ“Œ select_type ์นผ๋Ÿผ

์ฟผ๋ฆฌ๊ฐ€ ์–ด๋–ค ํƒ€์ž…์ธ์ง€ ๋‚˜ํƒ€๋‚ธ๋‹ค. ์ฟผ๋ฆฌ ํƒ€์ž…๋งŒ ๋ณด๋”๋ผ๋„ ๋Œ€์ถฉ ์–ด๋–ป๊ฒŒ ๊ฐœ์„ ํ•ด์•ผ ํ•˜๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ๋‹ค.
โœ” SIMPLE : ์„œ๋ธŒ์ฟผ๋ฆฌ๋‚˜ Union์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์€ ๋‹จ์ˆœ Select ์ฟผ๋ฆฌ๋ฅผ ์˜๋ฏธํ•œ๋‹ค. (Join๋„ ๋‹จ์ˆœ ์ฟผ๋ฆฌ๋กœ ์ทจ๊ธ‰ํ•œ๋‹ค.)
โœ” PRIMARY : ์„œ๋ธŒ์ฟผ๋ฆฌ๋‚˜ Union๊ฐ€ ํฌํ•จ๋œ ์ฟผ๋ฆฌ. ๊ฐ€์žฅ ๋ฐ”๊นฅ์ชฝ Select๊ฐ€ PRIMARY๋กœ ํ‘œ๊ธฐ๋œ๋‹ค.
์ƒ๊ฐํ•ด๋ณด๋ฉด ๋‹น์—ฐํ•œ๊ฑฐ์ง€๋งŒ, ํ•œ ๊ฐœ์˜ ์ฟผ๋ฆฌ ์‹คํ–‰ ๊ณ„ํš์—์„œ SIMPLE ๊ณผ PRIMARY ๋Š” ๋ฐ˜๋“œ์‹œ ํ•˜๋‚˜๋งŒ ์กด์žฌํ•œ๋‹ค.
โœ” SUBQUERY : From์ ˆ ์ด์™ธ์— ์‚ฌ์šฉ๋œ ์„œ๋ธŒ ์ฟผ๋ฆฌ๋ฅผ ์˜๋ฏธํ•œ๋‹ค.

โœ” DERIVED : From์ ˆ์— ์‚ฌ์šฉ๋œ ์„œ๋ธŒ ์ฟผ๋ฆฌ๋ฅผ ์˜๋ฏธํ•œ๋‹ค. ๋ฉ”๋ชจ๋ฆฌ๋‚˜ ๋””์Šคํฌ์— ์ž„์‹œ ํ…Œ์ด๋ธ”์„ ๋งŒ๋“ ๋‹ค.
โœ” UNION : Union์„ ์‚ฌ์šฉํ•œ ๊ฒฝ์šฐ, ๋‘ ๋ฒˆ์งธ ์ดํ›„ ์ฟผ๋ฆฌ๋Š” UNION์œผ๋กœ ํ‘œ์‹œ๋œ๋‹ค. ์ฒซ๋ฒˆ์งธ ์ฟผ๋ฆฌ๋Š” Union ๊ฒฐ๊ณผ๋ฅผ ๋Œ€ํ‘œํ•˜๋Š” DERIVED ํƒ€์ž…์„ ๊ฐ–๊ฒŒ ๋œ๋‹ค.

โœ” DEPENDENT UNION : ๋‚ด๋ถ€ ์ฟผ๋ฆฌ๊ฐ€ ์™ธ๋ถ€์˜ ๊ฐ’์„ ์ฐธ์กฐํ•  ๋•Œ DEPENDENT ํ‚ค์›Œ๋“œ๊ฐ€ ์ถ”๊ฐ€๋œ๋‹ค. Union์œผ๋กœ ๊ฒฐํ•ฉ๋œ ์ฟผ๋ฆฌ๊ฐ€ ์™ธ๋ถ€ ์ฟผ๋ฆฌ์— ์˜ํ•ด ์˜ํ–ฅ์„ ๋ฐ›๋Š”๋‹ค๋Š” ์˜๋ฏธ.
โœ” DEPENDENT SUBQUERY : From ์ ˆ ์ด์™ธ์— ์‚ฌ์šฉ๋œ ์„œ๋ธŒ์ฟผ๋ฆฌ๊ฐ€ ๋ฐ”๊นฅ์ชฝ Select ์ฟผ๋ฆฌ(์™ธ๋ถ€ ๊ฐ’)์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ 
โœ” DEPENDENT DERIVED : ๊ธฐ์กด์—๋Š” From ์ ˆ์˜ ์„œ๋ธŒ ์ฟผ๋ฆฌ์— ์™ธ๋ถ€ ์นผ๋Ÿผ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์—ˆ์œผ๋‚˜, MySQL 8.0๋ถ€ํ„ฐ๋Š” ๊ฐ€๋Šฅํ•˜๋‹ค. ๊ทธ๋ž˜์„œ Lateral Join์œผ๋กœ From ์ ˆ์˜ ์„œ๋ธŒ ์ฟผ๋ฆฌ๊ฐ€ ์™ธ๋ถ€ ์นผ๋Ÿผ์„ ์ฐธ์กฐํ–ˆ์„ ๋•Œ ํ•ด๋‹น ํƒ€์ž…์ด ์‚ฌ์šฉ๋œ๋‹ค. 

โœ” UNION RESULT : Union์˜ ๊ฒฐ๊ณผ๋ฅผ ๋‹ด๋Š” ์ž„์‹œํ…Œ์ด๋ธ”์„ ์˜๋ฏธํ•œ๋‹ค. ์ฐธ๊ณ ๋กœ MySQL8.0 ๋ถ€ํ„ฐ๋Š” Union ALL์„ ์‚ฌ์šฉํ•  ๋•Œ ์ž„์‹œ ํ…Œ์ด๋ธ”์„ ์ƒ์„ฑํ•˜์ง€ ์•Š๋Š”๋‹ค.
โœ” UNCACHEABLE SUBQUERY : SUBQUERY๋ฅผ ์‚ฌ์šฉํ–ˆ๋Š”๋ฐ ํŠน์ • ์กฐ๊ฑด ๋•Œ๋ฌธ์— ์บ์‹œ๋ฅผ ์ด์šฉํ•  ์ˆ˜ ์—†์„ ๋•Œ ํ‘œ๊ธฐ๋œ๋‹ค.
์ด๋Š” ์‚ฌ์šฉ์ž ๋ณ€์ˆ˜๋‚˜ UUID, RAND() ๊ฐ™์€ ๊ฐ’์ด ์„œ๋ธŒ์ฟผ๋ฆฌ์— ๋“ค์–ด ๊ฐ”์Œ์„ ์˜๋ฏธํ•œ๋‹ค.
โœ” MATERIALIZED : From ์ ˆ์ด๋‚˜ IN (subqurey) ์—์„œ ์„œ๋ธŒ์ฟผ๋ฆฌ ์ตœ์ ํ™”๋ฅผ ์œ„ํ•ด ์‚ฌ์šฉ๋œ๋‹ค.
๋ณดํ†ต ์ด๋Ÿฐ ๊ฒฝ์šฐ ์„œ๋ธŒ ์ฟผ๋ฆฌ๋Š” ์žฌ๊ปด๋‘๊ณ  ์™ธ๋ถ€ ์ฟผ๋ฆฌ์˜ ํ…Œ์ด๋ธ”์„ ๋จผ์ € ์ฝ์–ด์„œ ๋น„ํšจ์œจ์ ์œผ๋กœ ์‹คํ–‰๋˜๋Š”๋ฐ, ์ด๋ฅผ ์ตœ์ ํ™” ์‹œ์ผœ ์„œ๋ธŒ ์ฟผ๋ฆฌ์˜ ๋‚ด์šฉ์„ ์ž„์‹œํ…Œ์ด๋ธ”๋กœ ๊ตฌ์ฒดํ™”(Materialzed)ํ•œ ํ›„ ์™ธ๋ถ€ ํ…Œ์ด๋ธ”๊ณผ ์กฐ์ธํ•˜๋Š” ํ˜•ํƒœ๋กœ ์‹คํ–‰๋œ๋‹ค.
๋‹ค๋งŒ ๊ฒฐ๊ตญ ์ž„์‹œํ…Œ์ด๋ธ”์„ ์ถ”๊ฐ€๋กœ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ ๋ณดํ†ต ๊ทน์ ์ธ ์„ฑ๋Šฅ ํ–ฅ์ƒ์€ ๊ธฐ๋Œ€ํ•˜๊ธฐ ์–ด๋ ต๋‹ค. ๊ทธ๋ƒฅ ์กฐ๊ธˆ ๋” ์ข‹์€ ์ •๋„

๊ธฐ๋ณธ์ ์œผ๋กœ DEPENDENT๋Š” ์™ธ๋ถ€ ์ฟผ๋ฆฌ์— ์˜์กด์„ฑ์ด ์žˆ์œผ๋ฏ€๋กœ ์„ฑ๋Šฅ์ด ๋Š๋ฆฌ๋‹ค.

๋˜ํ•œ DERIVED ๊ฐ™์ด ์ž„์‹œ ํ…Œ์ด๋ธ”์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋“ค์€ ๋””์Šคํฌ์— ์ž„์‹œํ…Œ์ด๋ธ”์ด ๋งŒ๋“ค์–ด์งˆ ์œ„ํ—˜์ด ์žˆ๋‹ค. ๊ทธ๋ž˜์„œ Join์œผ๋กœ ์ฟผ๋ฆฌ๋ฅผ ์ˆ˜์ •ํ•ด ์ž„์‹œํ…Œ์ด๋ธ”์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋„๋ก ์ œ๊ฑฐํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

 

 

๐Ÿ“Œ table ์นผ๋Ÿผ

๋ณด๋ฉด ์•Œ๊ฒ ์ง€๋งŒ ์‹คํ–‰๊ณ„ํš์„ ํ™•์ธ ํ•  ๋•Œ, SELECT ์ฟผ๋ฆฌ๋กœ ๋ถ„๋ฅ˜ํ•˜๋Š”๊ฒŒ ์•„๋‹ˆ๋ผ ํ…Œ์ด๋ธ” ๋‹จ์œ„๋กœ ๋ถ„๋ฅ˜ํ•ด์„œ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜จ๋‹ค.
๊ทธ๋ž˜์„œ table ์นผ๋Ÿผ์„ ํ†ตํ•ด ์–ด๋–ค ํ…Œ์ด๋ธ”์— ๋Œ€ํ•œ ์ •๋ณด์ธ์ง€๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค. ์ฐธ๊ณ ๋กœ <>๋Š” ์ž„์‹œ ํ…Œ์ด๋ธ”์„ ์˜๋ฏธํ•œ๋‹ค.
table ํ•ญ๋ชฉ์ด <DERIVED2>์ธ ๊ฒฝ์šฐ, ID:2๋ฅผ ์ˆ˜ํ–‰ํ•œ ํ›„ ์ง„ํ–‰๋œ๋‹ค๋Š” ์˜๋ฏธ.

 

 

๐Ÿ“Œ partitions ์นผ๋Ÿผ

ํŒŒํ‹ฐ์…”๋‹(partitioning)ํ•˜์—ฌ ํ…Œ์ด๋ธ”์„ ๊ด€๋ฆฌํ•  ๋•Œ ์–ด๋–ค ํŒŒํ‹ฐ์…˜์„ ์ฝ์—ˆ๋Š”์ง€ ์•Œ๋ ค์ฃผ๋Š” ์ •๋ณด์ด๋‹ค. 
MYSQL 8.0๋ถ€ํ„ฐ๋Š” ๊ธฐ๋ณธ์œผ๋กœ ๋ณด์ด๋Š”๋ฐ, ์ด์ „ ๋ฒ„์ „์—์„œ๋Š” EXPLAIN PARTITION ์˜ต์…˜์„ ์ค˜์•ผ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

 


๐Ÿ“Œ type ์นผ๋Ÿผ

์‹คํ–‰๊ณ„ํš ํŠœ๋‹์— ํ•ต์‹ฌ์ ์ธ ์นผ๋Ÿผ์ด๋‹ค. ์‹คํ–‰ ๊ณ„ํš์ด ์–ด๋–ป๊ฒŒ ์ธ๋ฑ์Šค๋ฅผ ์ฐธ์กฐํ–ˆ๋Š”์ง€๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค.
์ฐธ๊ณ ๋กœ ์•ž์˜ ์ˆซ์ž (1~12)๋Š” ํ‰๊ท ์ ์ธ ์ธ๋ฑ์Šค ํšจ์œจ์„ ์ ์–ด๋…ผ ๊ฒƒ. 1. ALL์ด ๊ฐ€์žฅ ๋Š๋ฆฌ๊ณ  12. system ๊ฐ€ ๊ฐ€์žฅ ๋น ๋ฅด๋‹ค.

1. ALL : ํ’€ ํ…Œ์ด๋ธ” ์Šค์บ”์ด๋‹ค. ์ธ๋ฑ์Šค์— ๊ฐ’์ด ์—†์–ด B-TREE ์˜ ๋๊นŒ์ง€ ํƒ์ƒ‰ํ•˜์—ฌ ๋””์Šคํฌ ํŽ˜์ด์ง€๋ฅผ ์ฝ์–ด์„œ ์ฐพ์€ ๊ฒฝ์šฐ.
2. index : ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์ธ๋ฑ์Šค๋ฅผ ์ฒ˜์Œ~๋๊นŒ์ง€ ๋‹ค ์ฝ์€ ๊ฒฝ์šฐ. ๋‘๊ฐ€์ง€ ์กฐ๊ฑด์—์„œ ๋ฐœ์ƒํ•œ๋‹ค
- ์ธ๋ฑ์Šค ์Šค์บ” (range, const, ref)๊ฐ€ ๋ถˆ๊ฐ€๋Šฅ + ์ธ๋ฑ์Šค์— ํฌํ•จ๋œ ์นผ๋Ÿผ๋งŒ์œผ๋กœ ์ฒ˜๋ฆฌ ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ
- ์ธ๋ฑ์Šค ์Šค์บ” (range, cosnt, ref)๊ฐ€ ๋ถˆ๊ฐ€๋Šฅ + ์ธ๋ฑ์Šค๋งŒ ์ด์šฉํ•ด ์ •๋ ฌ์ด๋‚˜ ๊ทธ๋ฃนํ•‘์ด ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ

3. index_merge : 2๊ฐœ ์ด์ƒ์˜ ์ธ๋ฑ์Šค๋ฅผ ์ด์šฉํ•ด ๊ฒฐ๊ณผ๋ฅผ ํ•ฉ์น˜๋Š” ๋ฐฉ์‹. ์šฐ์„  ์ˆœ์œ„๊ฐ€ range๋ณด๋‹ค ๋†’์ง€๋งŒ ํšจ์œจ์ ์ด์ง„ ์•Š๋‹ค.
4. range : ์ธ๋ฑ์Šค ๋ ˆ์ธ์ง€ ์Šค์บ”, ๊ฐ’์ด ์•„๋‹ˆ๋ผ ์ธ๋ฑ์Šค ๋ฒ”์œ„๋กœ ๊ฒ€์ƒ‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค. < > IS NULL BETWEEN LINK IN...
๋‹ค๋งŒ ํ†ต์ƒ์ ์œผ๋กœ ์ธ๋ฑ์Šค๋ฅผ ํƒ”๋‹ค๊ณ  ํ•˜๋ฉด range, const, ref๋ฅผ ๋ฌถ์–ด์„œ ์นญํ•œ๋‹ค.

5. index_subquery : IN ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์กฐ๊ฑด์— ๋‚˜์˜ค๋Š” ๊ฐ’์ด ์œ ๋‹ˆํฌํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ(=์ด์ƒํ•œ ์ฟผ๋ฆฌ) ์ธ๋ฑ์Šค๋ฅผ ์ด์šฉํ•˜์—ฌ ์ค‘๋ณต์„ ์ œ๊ฑฐํ•˜๋Š” ์šฉ๋„๋กœ ํ•ด๋‹น ์ธ๋ฑ์Šค๊ฐ€ ์‚ฌ์šฉ๋œ๋‹ค.
6. unique_subqurey : where ์กฐ๊ฑด์— In (subqurey) ํ˜•ํƒœ๊ฐ€ ์žˆ์„ ๋•Œ ์‚ฌ์šฉ๋œ๋‹ค. ์„œ๋ธŒ์ฟผ๋ฆฌ์—์„œ ์œ ๋‹ˆํฌํ•œ ๊ฐ’๋งŒ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ฒฝ์šฐ๋ฅผ ํ•ด๋‹น ์ธ๋ฑ์Šค๊ฐ€ ์‚ฌ์šฉ๋œ๋‹ค.

7. ref_or_null : ref + IS NULL ์˜ ํ˜•ํƒœ. ref๋ณด๋‹ค ๋Š๋ฆฌ๋‹ค. ๋ณดํ†ต ์‹ค์ œ ์„œ๋น„์Šค์˜ ์‹คํ–‰ ๊ณ„ํš์—์„œ๋Š” ๋ณผ์ผ์ด ๊ฑฐ์˜ ์—†๋‹ค.
8. fulltext : ์ „๋ฌธ(full) ๊ฒ€์ƒ‰ ์ธ๋ฑ์Šค๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋ ˆ์ฝ”๋“œ์— ์ ‘๊ทผํ•˜๋Š” ๋ฐฉ๋ฒ•. ์ „๋ฌธ ๊ฒ€์ƒ‰ํ•  ์นผ๋Ÿผ์— ์ธ๋ฑ์Šค๊ฐ€ ์žˆ์–ด์•ผํ•œ๋‹ค.
MATCH ... AGAINST .. ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•˜๋Š”๋ฐ ๋‹น์žฅ ์‚ฌ์šฉํ• ์ผ์€ ์—†์œผ๋‹ˆ ์ผ๋‹จ ๋„˜์–ด๊ฐ€์ž.

9. ref : JOIN ์ˆœ์„œ์— ์ƒ๊ด€์—†์ด ์‚ฌ์šฉ๋œ๋‹ค. PK๋‚˜ ์œ ๋‹ˆํฌ ์ธ๋ฑ์Šค๋“ฑ ์ œ์•ฝ๋„ ์ƒ๊ด€์—†์ด ์‚ฌ์šฉ๋˜๋ฉฐ ๋™๋“ฑ ์กฐ๊ฑด(equal)์ด ์‚ฌ์šฉ๋  ๋•Œ ์ด์šฉํ•˜๋Š” ์ธ๋ฑ์Šค ์ ‘๊ทผ ๋ฐฉ์‹์ด๋‹ค. ์ƒ๋‹นํžˆ ๋น ๋ฅด๋‹ค.
10. eq_ref : ์—ฌ๋Ÿฌ ํ…Œ์ด๋ธ”์ด JOIN ๋˜๋Š” ์ฟผ๋ฆฌ์—๋งŒ ๋ฐœ์ƒํ•œ๋‹ค. ์กฐ์ธ์—์„œ ์ฒ˜์Œ ์ฝ์„ ํ…Œ์ด๋ธ”์˜ ์นผ๋Ÿผ ๊ฐ’์ด ๋‚˜์ค‘์— ๋˜ ์ฝ๋Š” ํ…Œ์ด๋ธ”์˜ PK, ์œ ๋‹ˆํฌ ์ธ๋ฑ์Šค ์นผ๋Ÿผ์˜ ๋™๋“ฑ ์กฐ๊ฑด์—์„œ ์‚ฌ์šฉ๋  ๋•Œ ์‚ฌ์šฉ๋˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค. 
์ฆ‰ ref์—์„œ ๋ฐ˜๋“œ์‹œ 1๊ฑด๋งŒ ์กด์žฌํ•œ๋‹ค๋Š” ๋ณด์žฅ์žˆ๋Š” ๊ฒฝ์šฐ ์‚ฌ์šฉ๋˜๋Š” ํƒ€์ž…์ด๋ผ๊ณ  ์ดํ•ดํ•˜๋ฉด ๋œ๋‹ค. ๋” ๋น ๋ฅด๋‹ค.

11. const : ์œ ๋‹ˆํฌ ์ธ๋ฑ์Šค ์Šค์บ”, ์ฟผ๋ฆฌ์— PK/์œ ๋‹ˆํฌ ์นผ๋Ÿผ์„ ์ด์šฉํ•˜๋Š” where ์กฐ๊ฑด์ด ์žˆ๊ณ , ๊ทธ ๊ฒฐ๊ณผ๊ฐ€ 1๊ฑด์ผ ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค. ๋‹จ ์‹คํ–‰ ์ „ ๊ฒฐ๊ณผ๊ฐ€ 1๊ฐœ๋ฐ–์— ์—†์Œ์„ DBMS๊ฐ€ ์˜ˆ์ธกํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ์—๋งŒ ์‚ฌ์šฉ๋œ๋‹ค.

12. system: ํ…Œ์ด๋ธ”์— ๋ ˆ์ฝ”๋“œ๊ฐ€ 1๊ฑด ์ดํ•˜์ผ ๋•Œ ์ ‘๊ทผ๋ฐฉ๋ฒ•. MySQL์˜ InnoDB์—์„œ๋Š” ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

 


๐Ÿ“Œ possible_keys ์นผ๋Ÿผ

์˜ตํ‹ฐ๋งˆ์ด์ €๊ฐ€ ์‚ฌ์šฉ์„ ๊ณ ๋ คํ•œ ํ›„๋ณด ์ธ๋ฑ์Šค ๋ชฉ๋ก์ด๋‹ค. 

 


๐Ÿ“Œ key ์นผ๋Ÿผ

์‹ค์ œ ์‚ฌ์šฉํ•œ ์ธ๋ฑ์Šค์ด๋‹ค. (possible_keys์ค‘ ํ•˜๋‚˜) ์ธ๋ฑ์Šค๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•˜๋‹ค๋ฉด null์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

 


๐Ÿ“Œ key_len ์นผ๋Ÿผ

์ธ๋ฑ์Šค๋ฅผ ๋‹ค์ค‘ ์นผ๋Ÿผ์œผ๋กœ ์‚ฌ์šฉํ–ˆ์„ ๋•Œ, ์ธ๋ฑ์Šค ์ค‘ ๋ช‡ ๋ฐ”์ดํŠธ๊นŒ์ง€ ์‚ฌ์šฉํ–ˆ๋Š”์ง€ ์•Œ๋ ค์ค€๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด SELECT * FROM table WHERE no=2; ์—์„œ key_len์˜ ๊ฐ’์ด 4๊ฐ€ ๋‚˜์™”๋‹ค๋ฉด ์ด๋Š” Integer(=4๋ฐ”์ดํŠธ)ํ•œ ๊ฐœ๋งŒ ์‚ฌ์šฉํ–ˆ์Œ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค. ์ฆ‰ ๋‹ค์ค‘์นผ๋Ÿผ ์ธ๋ฑ์Šค๋ฅผ ์กฐํšŒํ•  ๋•Œ ๋ชจ๋“  ๊ฐ’์„ ์‚ฌ์šฉํ–ˆ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ํŒ๋‹จํ•  ์ˆ˜ ์žˆ๋‹ค.

 


๐Ÿ“Œ ref ์นผ๋Ÿผ (type - ref์ผ ๋•Œ)

type์—์„œ ref (๋™๋“ฑ์กฐ๊ฑด์ด ์‚ฌ์šฉ๋  ๋•Œ ์ธ๋ฑ์Šค ์ ‘๊ทผ๋ฐฉ๋ฒ•, 1๊ฐœ์ž„์„ ๋ณด์žฅ์€ ๋ชปํ•จ)๊ฐ€ ์‚ฌ์šฉ๋ฌ๋‹ค๋ฉด ref ์นผ๋Ÿผ์ด ์ถ”๊ฐ€๋กœ ์ œ๊ณต๋œ๋‹ค.
์ด๋Š” ์–ด๋–ค ์นผ๋Ÿผ์ด ์กฐ๊ฑด์— ์‚ฌ์šฉ๋˜์—ˆ๋Š”์ง€๋ฅผ ๋ณด์—ฌ์ฃผ๋ฉฐ, ๋งŒ์•ฝ func๋ผ๊ณ  ํ‘œ์‹œ๋œ๋‹ค๋ฉด ๊ฐ€๊ณต๋œ ์นผ๋Ÿผ์ด ์‚ฌ์šฉ๋ฌ์Œ์„ ์˜๋ฏธํ•œ๋‹ค.

 


๐Ÿ“Œ row ์นผ๋Ÿผ

์˜ตํ‹ฐ๋งˆ์ด์ €๊ฐ€ ์˜ˆ์ธกํ•ด๋ณธ ์‚ฌ์šฉํ•  ๋ ˆ์ฝ”๋“œ ์ˆ˜์ด๋‹ค. ํ†ต๊ณ„์— ์˜ํ•œ ๊ฐ’์ด๋ผ์„œ ์‹ค์ œ ๋ ˆ์ฝ”๋“œ ์ˆ˜์™€ ์ผ์น˜ํ•˜์ง€๋Š” ์•Š๋Š”๋‹ค.

๊นŒ๋จน์—ˆ์„๊นŒ๋ด ํ•œ๋ฒˆ ๋” ๋ณด์—ฌ์ฃผ๋Š” EXPLAIN (์•„๋ฌด ์ฟผ๋ฆฌ) ์‹คํ–‰๊ณ„ํš ํ…Œ์ด๋ธ”

 

๐Ÿ“Œ Extra ์นผ๋Ÿผ

MySQL์ด SQL๋ฌธ์„ ์–ด๋–ป๊ฒŒ ์‹คํ–‰๊ณ„ํš์œผ๋กœ ๋งŒ๋“ค์—ˆ๋Š”์ง€์— ๋Œ€ํ•œ ๋ถ€๊ฐ€ ์ •๋ณด์ด๋‹ค. ์—ฌ๋Ÿฌ ๊ฐœ๊ฐ€ ๋™์‹œ์— ๋‚˜์˜ฌ ์ˆ˜ ์žˆ๋‹ค.
์™ธ์šฐ๊ธฐ์—๋Š” Extra ์ข…๋ฅ˜๊ฐ€ ๋„ˆ๋ฌด ๋งŽ๋‹ค. ๋‹ค๋งŒ ๋ฌธ๊ตฌ๋กœ ๋‚˜์˜ค๋ฏ€๋กœ ๋Œ€์ถฉ ์ฝ์–ด๋ณด๋ฉด ๋ฌด์Šจ ์˜๋ฏธ์ธ์ง€ ์ถ”์ธก ๊ฐ€๋Šฅํ•˜๋‹ค.

- const row not found : const ๋ฐฉ์‹์œผ๋กœ ์ฝ์—ˆ์ง€๋งŒ ๋ ˆ์ฝ”๋“œ๊ฐ€ 0๊ฐœ์ž…๋‹ˆ๋‹ค.
- distinct : ํ•„์š”ํ•œ ๊ฒƒ๋งŒ ์กฐ์ธํ•˜๊ณ  ์ค‘๋ณต๋œ ๊ฐ’์„ ์ œ๊ฑฐํ•˜์˜€์Šต๋‹ˆ๋‹ค.
- Full scan on Null key : where ์กฐ๊ฑด์— null์ด ๋“ค์–ด๊ฐˆ ์ˆ˜ ์žˆ๋Š” ๊ฐ’์„ ์‚ฌ์šฉํ–ˆ์Œ. null ๋œจ๋ฉด ํ’€ ์Šค์บ”์œผ๋กœ ๋ฐ”๊พธ๊ฒ ์Šต๋‹ˆ๋‹ค.
- Impossible Having : having์กฐ๊ฑด์— ๋งŒ์กฑ๋˜๋Š” ๋ ˆ์ฝ”๋“œ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ์ž˜๋ชป๋œ ์ฟผ๋ฆฌ์ž…๋‹ˆ๋‹ค.
- Impossible Where : where ์กฐ๊ฑด์ด ํ•ญ์ƒ False์ž…๋‹ˆ๋‹ค. ์ž˜๋ชป๋œ ์ฟผ๋ฆฌ์ž…๋‹ˆ๋‹ค.
- Impossible Where noticed after reading const table : ์ฟผ๋ฆฌ ์‹คํ–‰ํ•ด๋ณด๋‹ˆ Where์ด ํ•ญ์ƒ false์ž…๋‹ˆ๋‹ค. ์ž˜๋ชป๋œ ์ฟผ๋ฆฌ.
- No matching min/max row : Where ์กฐ๊ฑด์— ์ผ์น˜ํ•˜๋Š” ๋ ˆ์ฝ”๋“œ๊ฐ€ ์—†์–ด์„œ min() max()๊ฐ€ ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
- No matching row in const table : const ๋ฐฉ์‹์œผ๋กœ ์ ‘๊ทผํ•  ๋•Œ ์ผ์น˜ํ•˜๋Š” ๋ ˆ์ฝ”๋“œ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.
- No tables used : from ์ ˆ์ด ์—†์Šต๋‹ˆ๋‹ค. (from dual์œผ๋กœ ๋”๋ฏธ ํ…Œ์ด๋ธ” ์กฐํšŒํ•œ ๊ฒฝ์šฐ)
- Not exist : ๋‘ ํ…Œ์ด๋ธ” A, B์—์„œ ์—์„œ ํ•œ์ชฝ์—๋งŒ ๊ฐ’์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. โžก ์ด ๊ฒฝ์šฐ 2๊ฐ€์ง€ ์กฐ์ธ์„ ์‚ฌ์šฉํ•œ๋‹ค.
1. Anti-Join : NOT IN (subqurey) ๋˜๋Š” NOT EXISTS ์œผ๋กœ ํ˜„์žฌ ํ…Œ์ด๋ธ”์— ์—†๋Š” ๊ฐ’์„ ์กฐ์ธํ•˜๋Š” ๋ฐฉ๋ฒ•
2. Left Outer Join : ๋ ˆ์ฝ”๋“œ๊ฐ€ ๋งŽ์„ ๋•Œ ์•ˆํ‹ฐ ์กฐ์ธ ๋Œ€์‹  ๋ ˆ์ฝ”๋“œ ์กด์žฌ ์—ฌ๋ถ€๋งŒ ํŒ๋‹จ(NOT EXISTS)ํ•˜๋„๋ก ์ตœ์ ํ™”.

SELECT * 
FROM dept_emp de LEFT JOIN departments d ON de.dept_no = d.dept_no 
WHERE d.dept_no IS NULL; --NOT EXISTS

- Range checked for each record (index map : N) : ๋‘ ํ…Œ์ด๋ธ” ์กฐ์ธ์‹œ, Where ์กฐ๊ฑด์— ๋ณ€์ˆ˜๊ฐ€ ์—ฌ๋Ÿฌ๊ฐœ ์‚ฌ์šฉ๋˜์–ด ๊ณ„์† ๊ฐ’์ด ๋ฐ”๋€Œ๋Š” ๊ฒฝ์šฐ. ๋ ˆ์ฝ”๋“œ๋งˆ๋‹ค [์ธ๋ฑ์Šค ์‚ฌ์šฉ/ ํ’€์Šค์บ”]์ด ๋‹ฌ๋ผ์ง€๋Š” ์ฟผ๋ฆฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค๋Š” ์˜๋ฏธ.

- Scanned N databases : ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ๋ฉ”ํƒ€์ •๋ณด๋ฅผ ์กฐํšŒํ•œ ๊ฒฝ์šฐ 
- Select tables optimized away : MIN() MAX() ๋“ฑ์ด ์ธ๋ฑ์Šค๋ฅผ ์ด์šฉํ•ด ๋‹จ 1๊ฑด์˜ ์กฐํšŒ๋กœ ์ฐพ์„ ์ˆ˜ ์žˆ๊ฒŒ ์ž˜ ์ตœ์ ํ™” ๋œ ๊ฒฝ์šฐ.
- unique row not found : ๋‘๊ฐœ์˜ ํ…Œ์ด๋ธ”์„ PK๋‚˜ ์œ ๋‹ˆํฌ ์นผ๋Ÿผ์œผ๋กœ ์•„์šฐํ„ฐ ์กฐ์ธํ•  ๋•Œ, ์ผ์น˜ํ•˜๋Š” ๋ ˆ์ฝ”๋“œ๊ฐ€ ์•„์˜ˆ ์—†๋Š” ๊ฒฝ์šฐ
- Using filesort : ORDER BY๋ฅผ ์ธ๋ฑ์Šค๋กœ ์ฒ˜๋ฆฌํ•˜์ง€ ๋ชปํ•œ ๊ฒฝ์šฐ. MySQL์—์„œ ๊ฐ’์„ Sort buffer๋กœ ๋ณต์‚ฌํ•ด์„œ ์ •๋ ฌํ–ˆ์Œ์„ ๊ฒฝ๊ณ 
ํ”ํžˆ ๋ณผ ์ˆ˜ ์žˆ๋Š” ๋น„ํšจ์œจ์ ์ธ ์ผ€์ด์Šค์ด๋‹ค. ์ •๋ ฌ์„ ์‚ฌ์šฉํ•ด์„œ SQL์„ ํŠœ๋‹ํ•˜์ž.

 

- Using index : ์ปค๋ฒ„๋ง ์ธ๋ฑ์Šค, ๋ฐ์ดํ„ฐ ํŒŒ์ผ์„ ์•„์˜ˆ ์•ˆ์ฝ๊ณ  ์ฒ˜๋ฆฌ ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ. (* type ์นผ๋Ÿผ์˜ index๋Š” ํ’€์Šค์บ”์„ ์˜๋ฏธํ•จ.)
- Using index for group-by : ๋ฃจ์ฆˆ ์ธ๋ฑ์Šค ์Šค์บ”. Group By ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•ด ์ •๋ ฌ๋œ ์ธ๋ฑ์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ.
- Using Join Buffer : ์กฐ์ธ ๋ฒ„ํผ๋ฅผ ์‚ฌ์šฉํ–ˆ์Œ์„ ์˜๋ฏธํ•œ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ์กฐ์ธ์— ์‚ฌ์šฉ๋˜๋Š” ์นผ๋Ÿผ์€ ์ธ๋ฑ์Šค๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.
๋‘ ํ…Œ์ด๋ธ”์„ Join ํ–ˆ์„ ๋•Œ, ๋จผ์ € ์ฝ์€ ํ…Œ์ด๋ธ”์„ ๋“œ๋ผ์ด๋น™(Driving), ๋‚˜์ค‘์— ์ฝ์€ ํ…Œ์ด๋ธ”์€ ๋“œ๋ฆฌ๋ธ(Driven)์ด๋ผ ํ•œ๋‹ค.
๋‚˜์ค‘์— ์ฝ์€ ๋“œ๋ฆฌ๋ธ ํ…Œ์ด๋ธ”์— Join ์นผ๋Ÿผ ์ธ๋ฑ์Šค๊ฐ€ ์—†๋‹ค๋ฉด ์กฐ์ธ ๋ฒ„ํผ๋ฅผ ๋งŒ๋“ค์–ด์„œ ์ž ๊น ์ €์žฅํ•ด๋‘”๋‹ค. ์ด ๊ฒฝ์šฐ ์‚ฌ์šฉํ•œ๋‹ค.
+์œ ํšจํ•œ ์กฐ์ธ์กฐ๊ฑด์„ ์ ์ง€ ์•Š์•„์„œ, ๋ชจ๋“  ๊ฒฝ์šฐ์˜ ์ˆ˜ ๋ ˆ์ฝ”๋“œ๊ฐ€ ๋งŒ๋“ค์–ด์ง€๋Š” Cartesian Product ์กฐ์ธ๋„ ์กฐ์ธ๋ฒ„ํผ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

 

- Using union, Using intersect, Using sort_union,  : 2๊ฐœ ์ด์ƒ์˜ ๋‹ค์ค‘์ปฌ๋Ÿผ ์ธ๋ฑ์Šค๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ (type=index_merge) ๊ฒฐ๊ณผ๊ฐ€ ์–ด๋–ป๊ฒŒ ํ•ฉ์ณ์กŒ๋Š”์ง€๋ฅผ ์•Œ๋ ค์ค€๋‹ค. ์กฐ๊ฑด์ด OR์ด๋ผ ํ•ฉ์ง‘ํ•ฉ์œผ๋กœ ์ถ”์ถœํ–ˆ๋Š”์ง€, AND๋ผ ๊ต์ง‘ํ•ฉ์œผ๋กœ ์ถ”์ถœํ–ˆ๋Š”์ง€ ์•Œ๋ ค์ค€๋‹ค.

๋‹จ sort_union์€ ํ•ฉ์ง‘ํ•ฉ ์ถ”์ถœ๊ณผ ๊ฐ™์ง€๋งŒ ์—ฐ๊ฒฐ๋œ ๋ ˆ์ฝ”๋“œ๊ฐ€ ๋Œ€๋Ÿ‰์˜ range๋ฅผ ํ•„์š”ํ•˜๋Š” ์กฐ๊ฑด์ด๋ผ ํ•œ๋ฒˆ์— ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ PK๋งŒ ๋จผ์ € ์ฝ์–ด์„œ ์ •๋ ฌ โžก ๋ณ‘ํ•ฉํ•˜์—ฌ ๋ฐ˜ํ™˜ํ–ˆ์Œ์„ ์˜๋ฏธํ•œ๋‹ค.

- Using temporary : ์ž„์‹œํ…Œ์ด๋ธ”์„ ์‚ฌ์šฉ๋˜์—ˆ์Œ์„ ์˜๋ฏธํ•œ๋‹ค. ๋‹ค๋งŒ ์‚ฌ์šฉํ–ˆ๋Š”๋ฐ Using temporary๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ๋„ ์ข…์ข…์žˆ๋‹ค.
์ฐธ๊ณ ๋กœ ์ž„์‹œํ…Œ์ด๋ธ”์ด ์ƒ์„ฑ๋˜๋Š” ๊ฒฝ์šฐ๋Š” ๋Œ€์ถฉ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.
โœ” FROM ์ ˆ์— ์„œ๋ธŒ์ฟผ๋ฆฌ๋ฅผ ์“ฐ๋ฉด ๋ฌด์กฐ๊ฑด ์ž„์‹œํ…Œ์ด๋ธ”(Derived table)์ด ์ƒ์„ฑ๋œ๋‹ค.
โœ” "COUNT(DISTINCT column1)" ๊ฐ™์€ ์ฟผ๋ฆฌ๋„ ์ธ๋ฑ์Šค๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ์— ์ž„์‹œ ํ…Œ์ด๋ธ”์ด ๋งŒ๋“ค์–ด์ง„๋‹ค.
โœ” UNION, UNION ALL์ด ์‚ฌ์šฉ๋œ ์ฟผ๋ฆฌ๋„ ํ•ญ์ƒ ์ž„์‹œ ํ…Œ์ด๋ธ”์„ ์‚ฌ์šฉํ•œ๋‹ค.
โœ” ์ธ๋ฑ์Šค๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ๋ชปํ•˜๋Š” ์ •๋ ฌ ์ž‘์—…๋„ ์ž„์‹œ ํ…Œ์ด๋ธ”์„ ์‚ฌ์šฉํ•œ๋‹ค.

- Using where : MySQL์—”์ง„์ด ์ฟผ๋ฆฌ๋ฅผ ๊ฐ€๊ณต/ํ•„ํ„ฐ๋ง ํ•œ ๊ฒฝ์šฐ ๋‚˜ํƒ€๋‚œ๋‹ค. ์ฒดํฌ ์กฐ๊ฑด์€ MySQL ์—”์ง„์—์„œ ์ฒ˜๋ฆฌํ•œ๋‹ค.

๋ฒ”์œ„ ์กฐ๊ฑด์€ ์Šคํ† ๋ฆฌ์ง€ ์—”์ง„์—์„œ ์ฒ˜๋ฆฌ ํ›„ ๋ ˆ์ฝ”๋“œ๋ฅผ ๋ฆฌํ„ดํ•˜์ง€๋งŒ, ์ฒดํฌ ์กฐ๊ฑด์€ Using where์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

SELECT * FROM table WHERE man_no BETWEEN 0 AND 10 AND gender = 'M';
-- ๋ฒ”์œ„์กฐ๊ฑด BETWEEN์€ ์Šคํ† ๋ฆฌ์ง€ ์—”์ง„์— ์˜ํ•ด 10๊ฐœ์˜ ๋ ˆ์ฝ”๋“œ๊ฐ€ ๋ฆฌํ„ด๋˜๊ณ  
-- ๊ฐ€์ ธ์˜จ 10๊ฐœ์ค‘์— ์ฒดํฌ ์กฐ๊ฑด gender='M' ์ธ ๊ฒƒ์„ MySQL์—”์ง„์— ์˜ํ•ด ํ•„ํ„ฐ๋ง๋˜์–ด Using Where ๋“ฑ์žฅ

 

- zero limit

๊ฐ„ํ˜น ์ฟผ๋ฆฌ ๋ฐ์ดํ„ฐ๋Š” ํ•„์š”์—†๊ณ , ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋งŒ ํ•„์š”ํ•œ ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค.

์ด ๋•Œ Limit 0๋“ฑ์„ ์‚ฌ์šฉํ•˜๋ฉด ์‹คํ–‰๊ณ„ํš์— zero limit์ด ๋‚˜์˜ค๋Š”๋ฐ, ์ด๋Š” ์•„์˜ˆ ๋ฐ์ดํ„ฐ ์กฐํšŒ๋ฅผ ํ•˜์ง€ ์•Š์•˜์Œ์„ ์˜๋ฏธํ•œ๋‹ค.

 

 

๐Ÿ“Œ Filtered ์นผ๋Ÿผ (Extra - Using Where ์•Œ ๋•Œ)

MySQL8.0์—์„œ๋Š” ๊ธฐ๋ณธ์œผ๋กœ ๋‚˜์˜ค๊ณ , ์ด์ „ ๋ฒ„์ „์—์„œ๋Š” EXPLAIN EXTENDED๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ๋‚˜์˜จ๋‹ค.
Extra ์นผ๋Ÿผ์—์„œ Using where์ด ๋œฌ ๊ฒฝ์šฐ (= MySQL์ด ๋ณ„๋„์˜ ํ•„ํ„ฐ๋ง, ๊ฐ€๊ณต์„ ํ•œ ๊ฒฝ์šฐ)
์–ผ๋งˆ๋‚˜ ๋งŽ์€ ๋ ˆ์ฝ”๋“œ๊ฐ€ ํ•„ํ„ฐ๋ง ๋˜์—ˆ๋Š”์ง€ ๋‚˜ํƒ€๋‚ธ๋‹ค. ๋‹ค๋งŒ ์ด๋„ ์‹ค์ œ ๊ฒฐ๊ณผ๊ฐ€ ์•„๋‹ˆ๋ผ, ํ†ต๊ณ„์— ๊ธฐ๋ฐ˜ํ•œ ์˜ˆ์ธก ๊ฐ’์ด๋‹ค.

'๐ŸŒฑBackend > DB(MySQL,PostgreSQL)' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

PostgreSQL ์™€ vaccum์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์ž.  (2) 2024.01.21
์ •๋ฆฌ์ค‘-6  (0) 2021.10.27
์ •๋ฆฌ์ค‘ - 4  (0) 2021.10.20
์ •๋ฆฌ์ค‘ - 3  (0) 2021.10.20
์ •๋ฆฌ์ค‘ -2  (0) 2021.10.20

๋ธ”๋กœ๊ทธ์˜ ์ •๋ณด

JiwonDev

JiwonDev

ํ™œ๋™ํ•˜๊ธฐ