Slow Query ํ™•์ธ๋ฒ• (in Mysql, Postgresql)

2023. 12. 13. 16:55ใ†Database

๋Š๋ฆฐ ์ฟผ๋ฆฌ๋ฅผ ๊ฐœ์„ ํ•˜๋Š” ๊ฒƒ์€ ์‚ฌ์šฉ์ž์˜ ์ž…์žฅ์—์„œ๋„ ์ค‘์š”ํ•˜์ง€๋งŒ DB ๋ ˆ๋ฒจ์˜ ํšจ์œจ์  ์ž์›๊ด€๋ฆฌ๋ฅผ ์œ„ํ•ด์„œ๋„ ๊ผญ ํ•„์š”ํ•œ ์ผ์ด๋‹ค. 

์–ด๋–ป๊ฒŒ ์ฟผ๋ฆฌ์˜ ์‹คํ–‰ ์‹œ๊ฐ„๋“ค์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์„๊นŒ? ์ง์ ‘ ์ผ์ผ์ด ์‹คํ–‰์‹œ์ผœ๋ณด๋ฉด์„œ ์‹œ๊ฐ„์„ ์žฌ์•ผ ํ•˜๋‚˜? 

๋‹คํ–‰ํžˆ๋„ ์ผ๋ถ€ DB๋“ค์€ ๊ทธ๋“ค ์„œ๋ฒ„์—์„œ ์ˆ˜ํ–‰๋˜๋Š” ์ฟผ๋ฆฌ ์ค‘ ์„œ๋ฒ„์— ์•…์˜ํ–ฅ์„ ๋ฏธ์น  ์ˆ˜ ์žˆ๋Š” Slow Query(์Šฌ๋กœ์šฐ ์ฟผ๋ฆฌ)๋“ค์„ ๋”ฐ๋กœ ์ €์žฅํ•ด๋‘๊ณ , ์ด๋ฅผ ๊ฐœ๋ฐœ์ž๋“ค์ด ํ™•์ธํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๊ณ  ์žˆ๋‹ค.

์ด ๊ธ€์—์„œ๋Š” ์Šฌ๋กœ์šฐ ์ฟผ๋ฆฌ์˜ ํ™•์ธ์ด ์šฉ์ดํ•œ ๋‘ DB, Mysql๊ณผ Postgresql์—์„œ ์ด๋ฅผ ์„ค์ •ํ•˜๊ณ  ํ™•์ธํ•˜๋Š” ๋ฒ•์„ ๋‹ค๋ฃจ๋ ค๊ณ  ํ•œ๋‹ค.

 

Mysql

์„ค์ •๋ฒ•

Mysql์—์„œ๋Š” ์•„๋ž˜ ๋‚ด์šฉ์„ my.cnf์— ์ถ”๊ฐ€ํ•˜๋ฉด 1์ดˆ ์ด์ƒ ๊ฑธ๋ฆฌ๋Š” ์ฟผ๋ฆฌ๋ฅผ ์Šฌ๋กœ์šฐ ์ฟผ๋ฆฌ๋กœ ์ƒ์ •ํ•˜๊ณ  ์ด์— ๋Œ€ํ•œ ์ˆ˜์ง‘์ด ์‹œ์ž‘๋œ๋‹ค. ๋ฌผ๋ก  ์„ค์ • ํŒŒ์ผ์„ ์ˆ˜์ •ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— DB ์žฌ์‹œ์ž‘์€ ํ•„์š”ํ•˜๋‹ค.

slow_query_log = 1
long_query_time = 1

์œ„ ์„ค์ •์ด ์ œ๋Œ€๋กœ ์ ์šฉ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š”, mysql์— ์ ‘์†ํ•˜์—ฌ ์•„๋ž˜ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•ด๋ณด๋ฉด ํ™•์ธ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

SHOW GLOBAL VARIABLES LIKE 'slow_query_log';
SHOW GLOBAL VARIABLES LIKE 'long_query_time';

์ œ๋Œ€๋กœ ์˜ต์…˜์ด ์ ์šฉ๋˜์—ˆ๋‹ค๋ฉด, slow_query_log ๊ฐ’์€ 'ON'์ด ๋˜๊ณ , long_query_time ๊ฐ’์€ 1์ด ๋˜์–ด์žˆ๋‹ค.

ํ™•์ธ๋ฒ•

์Šฌ๋กœ์šฐ ์ฟผ๋ฆฌ ์„ค์ •์„ ์ œ๋Œ€๋กœ ์ ์šฉํ•˜๊ณ  ๋‚œ ๋’ค์—”, ์„ค์ •ํ•œ ๊ธฐ์ค€ ์‹œ๊ฐ„์„ ๋„˜๊ธฐ๋Š” ์ฟผ๋ฆฌ์— ๋Œ€ํ•ด์„œ๋Š” ๋กœ๊ทธ์— ์Œ“์ด๊ฒŒ ๋œ๋‹ค.

๋”ฐ๋ผ์„œ ์ด๋ฅผ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์Šฌ๋กœ์šฐ ์ฟผ๋ฆฌ ๋กœ๊ทธ ํŒŒ์ผ์˜ ์œ„์น˜๋ฅผ ๋จผ์ € ํ™•์ธํ•ด์•ผ ํ•œ๋‹ค. ์ด๋ฅผ ํ™•์ธํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

SHOW GLOBAL VARIABLES LIKE 'slow_query_log_file';

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

๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•  ๋•Œ ๋ถ€๊ฐ€์ ์œผ๋กœ ์ค„ ์ˆ˜ ์žˆ๋Š” ์˜ต์…˜๋“ค์ด ๋‹ค์–‘ํ•˜๋‚˜, ํ•ด๋‹น ๊ธ€์—์„œ๋Š” ํ‰๊ท  ์‹คํ–‰ ์‹œ๊ฐ„์„ ๊ธฐ์ค€์œผ๋กœ ์ƒ์œ„ 10๊ฐœ์˜ ์ฟผ๋ฆฌ ๋งŒ์„ ์ถœ๋ ฅํ•˜๋„๋ก ์˜ต์…˜์„ ์ฃผ๋„๋ก ํ•˜๊ฒ ๋‹ค. ๋” ์ƒ์„ธํ•œ ์˜ต์…˜์— ๋Œ€ํ•œ ์„ค๋ช…์€ ์•„๋ž˜ ๋งํฌ์˜ ๊ณต์‹๋ฌธ์„œ๋ฅผ ํ™•์ธํ•ด๋ณด๋ฉด ์ž˜ ๋‚˜์™€์žˆ๋‹ค.

 

MySQL :: MySQL 8.0 Reference Manual :: 4.6.10 mysqldumpslow — Summarize Slow Query Log Files

4.6.10 mysqldumpslow — Summarize Slow Query Log Files The MySQL slow query log contains information about queries that take a long time to execute (see Section 5.4.5, “The Slow Query Log”). mysqldumpslow parses MySQL slow query log files and summar

dev.mysql.com

ํ‰๊ท  ์‹คํ–‰ ์‹œ๊ฐ„์„ ๊ธฐ์ค€์œผ๋กœ ์ƒ์œ„ 10๊ฐœ์˜ ์ฟผ๋ฆฌ ๋งŒ์„ ์ถœ๋ ฅํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ๋ช…๋ น์–ด๋ฅผ ์ˆ˜ํ–‰ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

mysqldumpslow -s at -t 10 {์Šฌ๋กœ์šฐ ์ฟผ๋ฆฌ ๋กœ๊ทธํŒŒ์ผ ๊ฒฝ๋กœ}

๋ช…๋ น์–ด๋ฅผ ์ˆ˜ํ–‰ํ•˜๋ฉด ์ด์ œ ๊ฒฝ๋กœ์˜ ์Šฌ๋กœ์šฐ ์ฟผ๋ฆฌ ๋กœ๊ทธํŒŒ์ผ์„ ์ฝ์–ด๋“ค์ด๊ณ  ์ด๋ฅผ ํ† ๋Œ€๋กœ ๋ถ„์„ํ•˜์—ฌ ๊ฒฐ๊ณผ๋ฌผ์„ ์ถœ๋ ฅํ•œ๋‹ค. ๋กœ๊ทธ๊ฐ€ ๋งŽ์ด ์Œ“์ธ ๊ฒฝ์šฐ์—” ๋ถ„์„ํ•˜๋Š”๋ฐ ์‹œ๊ฐ„์ด ๋” ๋“ค ์ˆ˜ ์žˆ๋‹ค.

 

Postgresql

PG์—์„œ๋Š” ๊ตฌ๊ธ€๋ง ์‹œ ์Šฌ๋กœ์šฐ ์ฟผ๋ฆฌ๋ฅผ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•œ ๋ฐฉ๋ฒ•์ด ํฌ๊ฒŒ 3๊ฐ€์ง€ ์ •๋„ ์žˆ๋‹ค๊ณ  ํ•œ๋‹ค.

  1. ์Šฌ๋กœ์šฐ ์ฟผ๋ฆฌ ํŒ๋‹จ ๊ธฐ์ค€ ์‹œ๊ฐ„์„ ์„ค์ •ํ•˜๊ณ  ์ด๋ฅผ ์ดˆ๊ณผํ•˜๋Š” ์ฟผ๋ฆฌ๋“ค์„ ๋กœ๊ทธ์— ์Œ“๋Š” ๋ฐฉ๋ฒ•(Mysql์˜ ์Šฌ๋กœ์šฐ ์ฟผ๋ฆฌ ๋กœ๊ทธ ์ ์žฌ ๋ฐฉ์‹๊ณผ ์œ ์‚ฌ)
  2. ์ „์ฒด ์„œ๋ฒ„ ์‹คํ–‰ ์ฟผ๋ฆฌ์— ๋Œ€ํ•œ ์‹คํ–‰๊ณ„ํš์„ ๋กœ๊ทธ์— ์ ์žฌ
  3. ์ „์ฒด ์„œ๋ฒ„ ์‹คํ–‰ ์ฟผ๋ฆฌ์— ๋Œ€ํ•œ ํ†ต๊ณ„๊ฐ’์„ ํ…Œ์ด๋ธ”(๋ทฐ)๋ฅผ ํ†ตํ•ด ํ™•์ธํ•˜๋Š” ๋ฐฉ๋ฒ•(pg_stat_statements)

์ด ์ค‘ ์ฒซ๋ฒˆ์งธ ๋ฐฉ์‹์ด ์œ„์—์„œ ์„ค๋ช…ํ•œ Mysql์˜ ๋ฐฉ์‹๊ณผ ์œ ์‚ฌํ•˜์—ฌ ์ด๋ฅผ ์†Œ๊ฐœํ•˜๋ ค๊ณ  ํ–ˆ๋Š”๋ฐ, ๋กœ๊ทธ ํŒŒ์ผ ๋ถ„์„์„ ๋Œ€์‹  ์ง„ํ–‰ํ•ด์ฃผ๋Š” mysqldumpslow ๊ฐ™์€ ๋ช…๋ น์–ด๋ฅผ ์ฐพ์ง€ ๋ชปํ•ด์„œ ์‹ค์งˆ์ ์œผ๋กœ ์‚ฌ์šฉ์„ฑ์ด ๋ถ€์กฑํ•˜๋‹ค๊ณ  ํŒ๋‹จํ–ˆ๋‹ค.

๋Œ€์‹  ์„ธ๋ฒˆ์งธ ๋ฐฉ์‹์— ๋Œ€ํ•ด ์†Œ๊ฐœํ•˜๋„๋ก ํ•˜๊ฒ ๋‹ค.

์„ค์ •๋ฒ•

pg_stat_statements ํ™•์žฅ์„ ํ™œ์„ฑํ™”ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์šฐ์„  PG์˜ ์„ค์ •ํŒŒ์ผ์ธ postgresql.conf๋ฅผ ์ˆ˜์ •ํ•ด์•ผ ํ•œ๋‹ค.

ํŒŒ์ผ ๋‚ด shared_preload_libraries ๋ณ€์ˆ˜๊ฐ€ ์„ ์–ธ์ด ๋˜์–ด์žˆ๋Š”์ง€ ํ™•์ธํ•˜๊ณ , ์„ ์–ธ์ด ๋˜์–ด์žˆ์ง€ ์•Š๋‹ค๋ฉด ์•„๋ž˜์ฒ˜๋Ÿผ ์ž‘์„ฑํ•ด์ค€๋‹ค.

shared_preload_libraries = 'pg_stat_statements'

๋งŒ์•ฝ ์ด๋ฏธ ์„ ์–ธ์ด ๋˜์–ด ์žˆ๋‹ค๋ฉด ์ด๋ฏธ ์กด์žฌํ•˜๋Š” ๋ฌธ์ž์—ด ๋‚ด์— ์ฝค๋งˆ(,)๋กœ ๊ตฌ๋ถ„ํ•˜๊ณ  pg_stat_statements ๋ฅผ ์ถ”๊ฐ€ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

์„ค์ •ํŒŒ์ผ์„ ์ˆ˜์ •ํ•œ ๋’ค์—”, ์šฐ์„  DB ์„œ๋ฒ„๋ฅผ ์žฌ์‹œ์ž‘ ํ•ด์ฃผ์ž.

๊ทธ ๋’ค DB ์„œ๋ฒ„์— ์ ‘์†ํ•˜์—ฌ ์•„๋ž˜ ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•ด์„œ ํ™•์žฅ์„ ์‹คํ–‰ํ•ด์ฃผ์ž. 

CREATE EXTENSION pg_stat_statements;

์—ฌ๊ธฐ๊นŒ์ง€ ์™”๋‹ค๋ฉด ์ด์ œ ์ฟผ๋ฆฌ๋ฅผ ํ†ตํ•ด ์„œ๋ฒ„ ๋‚ด ์‹คํ–‰๋œ ์ฟผ๋ฆฌ๋“ค์˜ ํ†ต๊ณ„๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

ํ™•์ธ๋ฒ•

pg_stat_statements ๋ทฐ๊ฐ€ ๊ฐ–๋Š” ์นผ๋Ÿผ์˜ ์ข…๋ฅ˜๊ฐ€ ๊ฝค๋‚˜ ๋งŽ์•„์„œ ๊ฒฐ๊ณผ๋ฅผ ๋ณด๊ธฐํž˜๋“ค์ง€ ๋ชจ๋ฅด๊ฒ ์œผ๋‚˜, ๊ทธ๋Ÿผ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ๊ฐ€์žฅ ์‹ฌํ”Œํ•œ ๋ฐฉ๋ฒ•์€ ์•„๋ž˜ ์ฟผ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

SELECT * FROM pg_stat_statements;

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

pg_stat_statements ํ™•์žฅ์— ๋Œ€ํ•œ ์ƒ์„ธํ•œ ์„ค๋ช…์ด๋‚˜ ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰ํ–ˆ์„ ๋•Œ ๋‚˜์˜ค๋Š” ์นผ๋Ÿผ๋“ค์— ๋Œ€ํ•œ ์„ค๋ช…์ด ์ถ”๊ฐ€์ ์œผ๋กœ ํ•„์š”ํ•˜๋‹ค๋ฉด ์•„๋ž˜ ํ•œ๊ธ€ํ™”๋œ ๊ณต์‹๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ ํ•ด๋„ ๋  ๊ฒƒ ๊ฐ™๋‹ค.

 

pg_stat_statements

pg_stat_statements ๋ชจ๋“ˆ์€ ์„œ๋ฒ„์—์„œ ์‹คํ–‰ ๋˜์—ˆ๋˜ ์ฟผ๋ฆฌ๋“ค์— ๋Œ€ํ•œ ์‹คํ–‰ ํ†ต๊ณ„ ์ •๋ณด๋ฅผ ๋ณด์—ฌ์ค€๋‹ค. ์ด ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด, ๋จผ์ € shared_preload_libraries ์„œ๋ฒ„ ํ™˜๊ฒฝ ์„ค์ • ๊ฐ’์— pg_stat_statements ๊ฐ’์ด ์ถ”๊ฐ€ ๋˜์–ด ์žˆ์–ด

www.postgresql.kr