๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
  • Round and Round
DB/SQLP

[SQLP] 1-4. ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์บ์‹œ ์ตœ์ ํ™”

by ํ‰๊ธ€ํ‰๊ธ€ 2025. 2. 9.

๐Ÿงท ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์บ์‹œ ์ตœ์ ํ™”

๐Ÿ–‡๏ธ ๋ฐ”์ธ๋“œ ๋ณ€์ˆ˜

1. SQL ๊ณต์œ  ๋ฐ ์žฌ์‚ฌ์šฉ ๋‹จ์ 

์‚ฌ์šฉ์ž ์ •์˜ ํ•จ์ˆ˜/ ํ”„๋กœ์‹œ์ €, ํŠธ๋ฆฌ๊ฑฐ, ํŒจํ‚ค์ง€ ๋“ฑ ์˜ ๊ฒฝ์šฐ

 

์ด๋Ÿฌํ•œ ์˜ค๋ธŒ์ ํŠธ๋“ค์€ Stored Object๋กœ ๋ถ„๋ฅ˜๋˜๋ฉฐ, ์ƒ์„ฑ ์‹œ ๊ณ ์œ ํ•œ ์ด๋ฆ„์„ ๊ฐ–๋Š”๋‹ค. ์ƒ์„ฑ๊ณผ ๋™์‹œ์— ์ปดํŒŒ์ผ๋œ ์ƒํƒœ๋กœ ๋ฐ์ดํ„ฐ ๋”•์…”๋„ˆ๋ฆฌ์— ์ €์žฅ๋˜๋ฉฐ, ์‚ฌ์šฉ์ž๊ฐ€ ์‚ญ์ œํ•˜์ง€ ์•Š๋Š” ํ•œ ์˜๊ตฌ์ ์œผ๋กœ ๋ณด๊ด€๋œ๋‹ค. ์‹คํ–‰ ์‹œ์—๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์บ์‹œ์— ์ ์žฌ๋˜์–ด ์—ฌ๋Ÿฌ ์‚ฌ์šฉ์ž๊ฐ€ ๊ณต์œ ํ•˜๋ฉฐ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

SQL์˜ ๊ฒฝ์šฐ

 

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

 

IBM DB2์™€ ๊ฐ™์€ DBMS๋Š” SQL์„ ์˜๊ตฌ์ ์œผ๋กœ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜์ง€๋งŒ, Oracle์ด๋‚˜ SQL Server์™€ ๊ฐ™์€ DBMS๋Š” ๊ทธ๋ ‡์ง€ ์•Š๋‹ค. SQL ํ…์ŠคํŠธ๊ฐ€ ์ด๋ฆ„ ์—ญํ• ์„ ํ•˜๋ฏ€๋กœ, ์ž‘์€ ๋ถ€๋ถ„์ด๋ผ๋„ ๋‹ฌ๋ผ์ง€๋ฉด ์„œ๋กœ ๋‹ค๋ฅธ ๊ฐ์ฒด๋กœ ์ธ์‹๋œ๋‹ค. ๋ชจ๋“  SQL์„ ์˜๊ตฌ์ ์œผ๋กœ ์ €์žฅํ•˜๋ ค๋ฉด ๋ฐฉ๋Œ€ํ•œ ์ €์žฅ ๊ณต๊ฐ„์ด ํ•„์š”ํ•˜๋ฉฐ, ์ด๋กœ ์ธํ•ด SQL์„ ๊ฒ€์ƒ‰ํ•˜๋Š” ์†๋„๋„ ๋А๋ ค์งˆ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 

2. ๋ฐ”์ธ๋“œ ๋ณ€์ˆ˜์˜ ์ค‘์š”์„ฑ

๋™์‹œ ๋‹ค๋ฐœ์  ํ•˜๋“œ ํŒŒ์‹ฑ ๋ฐœ์ƒ

 

I/O ์ž‘์—…์ด ๊ฑฐ์˜ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋”๋ผ๋„, SQL ํ•˜๋“œ ํŒŒ์‹ฑ์ด ๋™์‹œ๋‹ค๋ฐœ์ ์œผ๋กœ ๋ฐœ์ƒํ•˜๋ฉด CPU ์‚ฌ์šฉ๋ฅ ์ด ๊ธ‰๊ฒฉํžˆ ์ƒ์Šนํ•˜๋ฉฐ DBMS์— ๋ถ€ํ•˜๋ฅผ ์ดˆ๋ž˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

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

๊ณต์œ  ๊ฐ€๋Šฅํ•œ SQL

 

๋™์‹œ๋‹ค๋ฐœ์  ํ•˜๋“œ ํŒŒ์‹ฑ ๋ฌธ์ œ๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ํŒŒ๋ผ๋ฏธํ„ฐ **Driven ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜๋Š”๋ฐ, ์—ฌ๊ธฐ์„œ ํ•ต์‹ฌ์ด ๋˜๋Š” ๊ฒƒ์ด ๋ฐ”๋กœ ๋ฐ”์ธ๋“œ ๋ณ€์ˆ˜๋‹ค. ๋ฐ”์ธ๋“œ ๋ณ€์ˆ˜๋ฅผ ํ™œ์šฉํ•˜๋ฉด, ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์บ์‹œ๋ฅผ ์กฐํšŒํ•  ๋•Œ ์•„๋ž˜์™€ ๊ฐ™์€ ๋‹จ์ผ SQL๋งŒ ๋ฐœ๊ฒฌ๋œ๋‹ค.

SELECT * FROM TABLE FROM ID = :1

 

์ด SQL์€ ์ตœ์ดˆ ์‹คํ–‰ ์‹œ ๋‹จ ํ•œ ๋ฒˆ๋งŒ ํ•˜๋“œ ํŒŒ์‹ฑ์ด ์ด๋ฃจ์–ด์ง€๊ณ , ์ดํ›„์—๋Š” ๋™์ผํ•œ ํ”„๋กœ์‹œ์ €๋ฅผ ์—ฌ๋Ÿฌ ์‚ฌ์šฉ์ž๊ฐ€ ๊ณต์œ ํ•˜๋ฉฐ ๋ฐ˜๋ณต ์žฌ์‚ฌ์šฉํ•˜๊ฒŒ ๋œ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด DBMS ๋ถ€ํ•˜๋ฅผ ํšจ๊ณผ์ ์œผ๋กœ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค.

  • ์ปค์„œ ์ƒ์„ฑ ํšŸ์ˆ˜ ๊ฐ์†Œ: ๋ถˆํ•„์š”ํ•œ ์ปค์„œ ์ƒ์„ฑ์„ ๋ฐฉ์ง€ํ•œ๋‹ค.
  • ๋ฉ”๋ชจ๋ฆฌ์™€ CPU ์‚ฌ์šฉ๋Ÿ‰ ์ ˆ๊ฐ: ๋™์ผํ•œ SQL์„ ๋ฐ˜๋ณต ์žฌ์‚ฌ์šฉํ•จ์œผ๋กœ์จ ๋ฉ”๋ชจ๋ฆฌ ์†Œ๋ชจ์™€ ํŒŒ์‹ฑ์— ์†Œ์š”๋˜๋Š” ์‹œ๊ฐ„์„ ์ค„์ธ๋‹ค.
  • DB ์„ฑ๋Šฅ ๋ฐ ํ™•์žฅ์„ฑ ํ–ฅ์ƒ: ๋ฆฌ์†Œ์Šค ์ ˆ์•ฝ(๋ฉ”๋ชจ๋ฆฌ์™€ CPU ์‚ฌ์šฉ๋Ÿ‰ ์ ˆ๊ฐ)์„ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์„ฑ๋Šฅ๊ณผ ํ™•์žฅ์„ฑ์„ ๊ฐœ์„ ํ•œ๋‹ค.
  • ๋™์‹œ ์‚ฌ์šฉ์ž ์ ‘์† ์‹œ ํšจ๊ณผ ๊ทน๋Œ€ํ™”: ํŠนํžˆ ๋™์‹œ ์ ‘์†์ž๊ฐ€ ๋งŽ์€ ํ™˜๊ฒฝ์—์„œ ๋”์šฑ ์ค‘์š”ํ•œ ์—ญํ• ์„ ํ•œ๋‹ค.

 

3. ๋ฐ”์ธ๋“œ ๋ณ€์ˆ˜์˜ ๋ถ€์ž‘์šฉ

๋ฐ”์ธ๋“œ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ตœ์ดˆ ์‹คํ–‰ ์‹œ ์ตœ์ ํ™” ๊ณผ์ •์„ ๊ฑฐ์ณ ์ƒ์„ฑ๋œ ์‹คํ–‰ ๊ณ„ํš์ด ์บ์‹œ์— ์ ์žฌ๋˜๊ณ , ์ดํ›„์—๋Š” ํ•ด๋‹น ๊ณ„ํš์„ ์žฌ์‚ฌ์šฉํ•˜๋ฉฐ ๊ฐ’์„ ๋ฐ”์ธ๋”ฉํ•˜์—ฌ ๋ฐ˜๋ณต์ ์œผ๋กœ ํ™œ์šฉ๋œ๋‹ค. ์ฆ‰, ์ตœ์ ํ™” ์‹œ์ ์€ ์กฐ๊ฑด์ ˆ์— ๊ฐ’์„ ๋ฐ”์ธ๋”ฉํ•˜๋Š” ์‹œ์ ์ด ์•„๋‹Œ ์‹คํ–‰ ์‹œ์ ์ด๋‹ค. ์ด๋Ÿฌํ•œ ํŠน์„ฑ์œผ๋กœ ์ธํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฌธ์ œ์ ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.

  • SQL ์ตœ์ ํ™” ์‹œ์ ์— ์กฐ๊ฑด์ ˆ ์ปฌ๋Ÿผ์˜ ํžˆ์Šคํ† ๊ทธ๋žจ ์ •๋ณด๋ฅผ ํ™œ์šฉํ•˜์ง€ ๋ชปํ•œ๋‹ค.
  • ๋ฐ์ดํ„ฐ ๋ถ„ํฌ๊ฐ€ ๊ท ์ผํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ, ํ‰๊ท  ๋ถ„ํฌ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ƒ์„ฑ๋œ ์‹คํ–‰ ๊ณ„ํš์ด ์ตœ์ ์˜ ์„ ํƒ์ด ์•„๋‹ ์ˆ˜ ์žˆ๋‹ค.

(1) ๋ฐ”์ธ๋“œ ๋ณ€์ˆ˜ Peeking

๋ฐ”์ธ๋“œ ๋ณ€์ˆ˜์˜ ๋ถ€์ž‘์šฉ์„ ๊ทน๋ณตํ•˜๊ธฐ ์œ„ํ•ด Oracle 9i๋ถ€ํ„ฐ ๋„์ž…๋œ ๊ธฐ๋Šฅ์ด๋‹ค. SQL์ด ์ฒ˜์Œ ํ•˜๋“œ ํŒŒ์‹ฑ๋  ๋•Œ, ๋ฐ”์ธ๋“œ ๋ณ€์ˆ˜์˜ ๊ฐ’์„ "์—ฟ๋ณด๊ณ (peeking)" ์ด๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ์ปฌ๋Ÿผ ๋ถ„ํฌ๋ฅผ ๊ณ ๋ คํ•œ ์‹คํ–‰ ๊ณ„ํš์„ ์ˆ˜๋ฆฝํ•œ๋‹ค. (SQL Server์˜ ๊ฒฝ์šฐ, Parameter Sniffing)

๊ทธ๋Ÿฌ๋‚˜ ์‹คํ–‰ ๊ณ„ํš์ด ์ ์ ˆํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ, SQL ์‹คํ–‰ ์†๋„๊ฐ€ ๊ฐ‘์ž๊ธฐ ๋А๋ ค์ง€๊ฑฐ๋‚˜, ์ž์ฃผ ์‹คํ–‰ ๊ณ„ํš์ด ๋ณ€๊ฒฝ๋˜์–ด ์„ฑ๋Šฅ ๋ณ€๋™์ด ์‹ฌํ•ด์ง€๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ด์œ ๋กœ ๋Œ€๋ถ€๋ถ„์˜ ์‹œ์Šคํ…œ์—์„œ ํ˜„์žฌ๋Š” ๋น„ํ™œ์„ฑํ™”๋œ ์ƒํƒœ๋กœ ์šด์˜๋œ๋‹ค.

(2) ์ ์‘์  ์ปค์„œ ๊ณต์œ (Adaptive Cursor Sharing)

Oracle 11g์— ๋„์ž…๋œ ๊ธฐ๋Šฅ์œผ๋กœ, ์ž…๋ ฅ๋œ ๋ฐ”์ธ๋“œ ๋ณ€์ˆ˜ ๊ฐ’์˜ ๋ถ„ํฌ์— ๋”ฐ๋ผ ์„œ๋กœ ๋‹ค๋ฅธ ์‹คํ–‰ ๊ณ„ํš์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค๊ณ„๋˜์—ˆ๋‹ค.

  1. ์„ ํƒ๋„๊ฐ€ ๋†’์€ ์กฐ๊ฑด์— ๋Œ€ํ•ด ํ…Œ์ด๋ธ”์„ Full Scan ํ•˜๋Š” ์‹คํ–‰ ๊ณ„ํš์„ ์ƒ์„ฑํ•˜๊ณ , ์ด๋ฅผ ์ปค์„œ๋กœ ์žฌ์‚ฌ์šฉ.
  2. ์„ ํƒ๋„๊ฐ€ ๋‚ฎ์€ ์กฐ๊ฑด์ด ์ž…๋ ฅ๋˜๋ฉด, ํžˆ์Šคํ† ๊ทธ๋žจ ์ •๋ณด๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ธ๋ฑ์Šค๋ฅผ ํ™œ์šฉํ•˜๋Š” ์ƒˆ๋กœ์šด ์‹คํ–‰ ๊ณ„ํš์„ ์ƒ์„ฑ.
  3. ๋‘ ๊ฐœ์˜ Child Cursor๊ฐ€ ์บ์‹œ์— ์ €์žฅ๋˜๊ณ , ์„ ํƒ๋„์— ๋”ฐ๋ผ ์ ํ•ฉํ•œ ์ปค์„œ๋ฅผ ์„ ํƒ์ ์œผ๋กœ ์žฌ์‚ฌ์šฉ.
  4. ํ˜„์žฌ ๋ฐ”์ธ๋“œ ๊ฐ’์— ์ ํ•ฉํ•œ ์ปค์„œ๊ฐ€ ์—†์„ ๊ฒฝ์šฐ, ํ•˜๋“œ ํŒŒ์‹ฑ์„ ํ†ตํ•ด ์ƒˆ๋กœ์šด ์‹คํ–‰ ๊ณ„ํš์„ ์ƒ์„ฑ.

์ด ๊ธฐ๋Šฅ์„ ํ™œ์šฉํ•˜๋ ค๋ฉด ์กฐ๊ฑด์ ˆ ์ปฌ๋Ÿผ์— ํžˆ์Šคํ† ๊ทธ๋žจ์ด ์ƒ์„ฑ๋˜์–ด ์žˆ์–ด์•ผ ํ•œ๋‹ค. ๋‹ค๋งŒ, ๊ธฐ์กด ์ปค์„œ๋ฅผ ๋จผ์ € ์‹คํ–‰ํ•œ ํ›„ ์„ฑ๋Šฅ์ด ์ข‹์ง€ ์•Š๋‹ค๊ณ  ํŒ๋‹จ๋˜์—ˆ์„ ๋•Œ ์ƒˆ๋กœ์šด ์‹คํ–‰ ๊ณ„ํš์„ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ, ์ฆ‰๊ฐ์ ์ธ ์ตœ์ ํ™”๊ฐ€ ์ด๋ฃจ์–ด์ง€์ง€ ์•Š๋Š” ๋‹จ์ ์ด ์žˆ๋‹ค.

(3) ์ž…๋ ฅ ๊ฐ’์— ๋”ฐ๋ผ SQL ๋ถ„๋ฆฌ

๋ฐ”์ธ๋“œ ๋ณ€์ˆ˜ ์‚ฌ์šฉ์— ๋”ฐ๋ฅธ ๋ถ€์ž‘์šฉ์„ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด, ๋ฐ”์ธ๋“œ ๊ฐ’์— ๋”ฐ๋ผ ์‹คํ–‰ ๊ณ„ํš์„ ๋ถ„๋ฆฌํ•˜๋Š” ๋ฐฉ์•ˆ์„ ๊ณ ๋ คํ•  ์ˆ˜ ์žˆ๋‹ค.

SELECT /*+ FULL(A)*/ *
FROM TABLE 
WHERE :O IN ('A','B')
AND OPTION = :O
UNION ALL
SELECT /*+ INDEX(A IDX)*/ *
FROM TABLE 
WHERE :O NOT IN ('A','B')
AND OPTION = :O

๋‹จ์ :

  • ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์บ์‹œ ํšจ์œจ ์ €ํ•˜: UNION ALL๋กœ ๊ฒฐํ•ฉ๋œ N๊ฐœ์˜ SQL์€ ์˜ตํ‹ฐ๋งˆ์ด์ €๊ฐ€ N๊ฐœ๋ฅผ ๋ชจ๋‘ ์ตœ์ ํ™”ํ•ด์•ผ ํ•˜๋ฉฐ, Shared Pool์—์„œ ๊ณต๊ฐ„ ๋‚ญ๋น„๊ฐ€ ๋ฐœ์ƒ.
  • CPU ๋ถ€ํ•˜ ์ฆ๊ฐ€:
    • Parse ๋‹จ๊ณ„์—์„œ ๋งŽ์€ CPU ๋ฆฌ์†Œ์Šค๋ฅผ ์†Œ๋ชจ.
    • ์‹คํ–‰๋˜์ง€ ์•Š๋Š” ๋ถ„๊ธฐ ์กฐ๊ฑด๊นŒ์ง€ ํฌํ•จ๋˜์–ด Execute ๋‹จ๊ณ„์—์„œ๋„ ์ถ”๊ฐ€์ ์ธ CPU ์‚ฌ์šฉ ๋ฐœ์ƒ.
  • ๋„คํŠธ์›Œํฌ ํŠธ๋ž˜ํ”ฝ ์ฆ๊ฐ€: SQL ๋ถ„๋ฆฌ๋กœ ์ธํ•ด ๋ฉ”์‹œ์ง€ ์ „์†ก๋Ÿ‰ ์ฆ๊ฐ€.

(4) ์˜ˆ์™ธ์ ์œผ๋กœ Literal ์ƒ์ˆ˜๊ฐ’ ์‚ฌ์šฉ

์กฐ๊ฑด์ ˆ ์ปฌ๋Ÿผ์˜ ๊ฐ’ ์ข…๋ฅ˜๊ฐ€ ์†Œ์ˆ˜์ผ ๊ฒฝ์šฐ, ๋ฐ”์ธ๋“œ ๋ณ€์ˆ˜ ๋Œ€์‹  Literal ์ƒ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋” ํšจ์œจ์ ์ผ ์ˆ˜ ์žˆ๋‹ค. ์ž…๋ ฅ ๊ฐ’ ์ข…๋ฅ˜๊ฐ€ ์ ๋‹ค๋ฉด ํ•˜๋“œ ํŒŒ์‹ฑ ๋ถ€ํ•˜๊ฐ€ ํฌ์ง€ ์•Š์œผ๋ฉฐ, ์˜ตํ‹ฐ๋งˆ์ด์ €๊ฐ€ ์ตœ์ ์˜ ์‹คํ–‰ ๊ณ„ํš์„ ์ˆ˜๋ฆฝํ•  ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์•„์ง€๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

Literal ์ƒ์ˆ˜ ์‚ฌ์šฉ์ด ์œ ๋ฆฌํ•œ ๊ฒฝ์šฐ:

  1. ๋ฒ”์œ„ ๊ฒ€์ƒ‰ ์กฐ๊ฑด: ๋ถ€๋“ฑํ˜ธ๋‚˜ BETWEEN ์กฐ๊ฑด์ ˆ์„ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ, Literal ์ƒ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ตœ์ ํ™”์— ์œ ๋ฆฌ
  2. ๋ฐฐ์น˜ ํ”„๋กœ๊ทธ๋žจ ๋ฐ ์ •๋ณด๊ณ„ ์‹œ์Šคํ…œ(DW/OLAP):
    • ๋Œ€๋ถ€๋ถ„ ๊ธฐ๊ฐ„ ์กฐ๊ฑด์„ ํฌํ•จํ•˜๋ฉฐ ๋ฒ”์œ„ ๊ฒ€์ƒ‰์ด ๋งŽ๊ธฐ ๋•Œ๋ฌธ์— Literal ์ƒ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ๋” ๋‚˜์€ ์‹คํ–‰ ๊ณ„ํš์ด ์ˆ˜๋ฆฝ
    • Long-running ์ฟผ๋ฆฌ์˜ ํŠน์„ฑ์ƒ ํŒŒ์‹ฑ ์‹œ๊ฐ„์€ ์ „์ฒด ์ฟผ๋ฆฌ ์‹œ๊ฐ„์—์„œ ํฐ ๋น„์ค‘์„ ์ฐจ์ง€ํ•˜์ง€ ์•Š์Œ.
  3. ์‚ฌ์šฉ ๋นˆ๋„๊ฐ€ ๋งค์šฐ ๋‚ฎ์€ ๊ฒฝ์šฐ:
    • ํ•˜๋“œ ํŒŒ์‹ฑ์— ๋”ฐ๋ฅธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์บ์‹œ ๋ถ€ํ•˜๊ฐ€ ๊ฑฐ์˜ ์—†์„ ๋•Œ, OLTP ์‹œ์Šคํ…œ์—์„œ๋„ ์ œํ•œ์ ์œผ๋กœ Literal ์ƒ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ.
    • ๋‹จ, OLTP ํ™˜๊ฒฝ์—์„œ๋Š” ํŠน์ˆ˜ํ•œ ๊ฒฝ์šฐ๋ฅผ ์ œ์™ธํ•˜๊ณ ๋Š” ๋ฐ˜๋“œ์‹œ ๋ฐ”์ธ๋“œ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์›์น™.
  4. ์กฐ๊ฑด์ ˆ ์ปฌ๋Ÿผ ๊ฐ’ ์ข…๋ฅ˜๊ฐ€ ์†Œ์ˆ˜์ผ ๊ฒฝ์šฐ: ๊ฐ’์˜ ์ข…๋ฅ˜๊ฐ€ ์ ์–ด ์บ์‹œ์— ์ €์žฅ๋œ SQL ์žฌ์‚ฌ์šฉ์ด ์šฉ์ดํ•œ ๊ฒฝ์šฐ Literal ์‚ฌ์šฉ์ด ํšจ๊ณผ์ ์ผ ์ˆ˜ ์žˆ์Œ.

 

๐Ÿ–‡๏ธ ์„ธ์…˜ ์ปค์„œ ์บ์‹ฑ ๊ธฐ๋Šฅ

(1) ๋ฌธ์ œ ๋ฐœ์ƒ

์ปค์„œ๋ฅผ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๋Š” ํ˜•ํƒœ๋กœ SQL์„ ์ž‘์„ฑํ•˜๋ฉด ํ•˜๋“œ ํŒŒ์‹ฑ์„ ์ตœ์†Œํ™”ํ•˜์—ฌ ์‹œ์Šคํ…œ ํ™•์žฅ์„ฑ์„ ๋†’์ผ ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํ•˜๋“œ ํŒŒ์‹ฑ์„ ํ”ผํ•˜๋”๋ผ๋„ SQL ๊ตฌ๋ฌธ์„ ๋ถ„์„ํ•˜๊ณ  ํ•ด์‹œ ๊ฐ’์„ ๊ณ„์‚ฐํ•˜๋ฉฐ, Library Cache ๋ž˜์น˜๋ฅผ ํš๋“ํ•œ ๋’ค ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์บ์‹œ์—์„œ ์ปค์„œ๋ฅผ ํƒ์ƒ‰ํ•˜๋Š” ์ž‘์—… ์ž์ฒด๊ฐ€ ๋ถ€๋‹ด์ด ๋˜๋Š” ์ž‘์—…์ด๋‹ค. ํŠนํžˆ, SQL์„ ๋™์‹œ ์‹คํ–‰ํ•˜๋Š” ๋นˆ๋„๊ฐ€ ๋†’์•„์ง€๋ฉด ๊ฒฝํ•ฉ์ด ๋ฐœ์ƒํ•˜์—ฌ ์‹œ์Šคํ…œ ๋ถ€ํ•˜๋ฅผ ์œ ๋ฐœํ•œ๋‹ค.

(2) ์„ธ์…˜ ์ปค์„œ ์บ์‹ฑ์„ ํ†ตํ•ด ๋ฌธ์ œ ํ•ด๊ฒฐ

Shared Pool์— ์œ„์น˜ํ•œ ๊ณต์œ  ์ปค์„œ๋ฅผ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•ด PGA๋กœ ์ธ์Šคํ„ด์Šคํ™”๋œ ์ปค์„œ๋ฅผ ์„ธ์…˜ ์ปค์„œ ๋ผ๊ณ  ํ•œ๋‹ค. ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•œ ํ›„ ์ปค์„œ๋ฅผ ๋‹ซ์œผ๋ฉด, ์„ธ์…˜ ์ปค์„œ์— ์˜ํ•ด ํ• ๋‹น๋œ ๋ฉ”๋ชจ๋ฆฌ์™€ ๊ณต์œ  ์ปค์„œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ๊ฐ€ ์ฆ‰์‹œ ํ•ด์ œ๋œ๋‹ค. ์ดํ›„ ๋™์ผํ•œ SQL์„ ์‹คํ–‰ํ•˜๋ฉด ์ปค์„œ๋ฅผ ์—ด๊ธฐ ์œ„ํ•ด ๋‹ค์‹œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์บ์‹œ ํƒ์ƒ‰ ๊ณผ์ •์„ ๊ฑฐ์ณ์•ผ ํ•œ๋‹ค.

์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์˜ค๋ผํด์€ ์ž์ฃผ ์‹คํ–‰๋˜๋Š” ์„ธ์…˜ ์ปค์„œ๋ฅผ ์„ธ์…˜ ์ปค์„œ ์บ์‹œ(Session Cursor Cache)์— ์ €์žฅํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด Parse Call์— ๋”ฐ๋ฅธ ๋ถ€ํ•˜๋ฅผ ํšจ๊ณผ์ ์œผ๋กœ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค.

(3) ๊ธฐ๋Šฅ ํ™œ์„ฑํ™”

  1. Parse Call ํšŸ์ˆ˜ ≥ 3์ธ ์ปค์„œ๋ฅผ ๋‹ซ์„ ๋•Œ, ํ•ด๋‹น ์ปค์„œ๋ฅผ ์„ธ์…˜ ์ปค์„œ ์บ์‹œ์— ์ €์žฅํ•œ๋‹ค.
  2. ์„ธ์…˜ ์ปค์„œ ์บ์‹œ์—๋Š” SQL ํ…์ŠคํŠธ์™€ ํ•จ๊ป˜ ๊ณต์œ  ์ปค์„œ๋ฅผ ์ฐธ์กฐํ•˜๋Š” ํฌ์ธํ„ฐ๋ฅผ ์ €์žฅํ•œ๋‹ค.
  3. ์ปค์„œ๋ฅผ ๋‹ซ๋”๋ผ๋„ ๊ณต์œ  ์ปค์„œ์— ๋Œ€ํ•œ ์ฐธ์กฐ๋ฅผ ์œ ์ง€ํ•˜๋ฏ€๋กœ, ์ดํ›„ ๋™์ผํ•œ SQL ์‹คํ–‰ ์‹œ ๋” ๋น ๋ฅด๊ฒŒ ์ปค์„œ๋ฅผ ์—ด ์ˆ˜ ์žˆ๋‹ค.

(4) ํŠน์ง•

  • LRU ์•Œ๊ณ ๋ฆฌ์ฆ˜ : ์„ธ์…˜ ์ปค์„œ ์บ์‹œ ๋‚ด์—์„œ๋„ LRU(Least Recently Used) ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ ์šฉํ•˜์—ฌ, ์ƒˆ๋กœ์šด ์—”ํŠธ๋ฆฌ๋ฅผ ์ €์žฅํ•  ๊ณต๊ฐ„์ด ํ•„์š”ํ•  ๊ฒฝ์šฐ ์‚ฌ์šฉ ๋นˆ๋„๊ฐ€ ๋‚ฎ์€ ์ปค์„œ๋ฅผ ๋ฐ€์–ด๋‚ธ๋‹ค.
  • Parse Call ๋ถ€ํ•˜ ๊ฐ์†Œ: Parse Call ์ž์ฒด๋ฅผ ์ค„์ด๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, Parse Call๋กœ ์ธํ•œ ์‹œ์Šคํ…œ ๋ถ€ํ•˜๋ฅผ ๊ฐ์†Œ์‹œํ‚ค๋Š” ๊ธฐ๋Šฅ์ด๋‹ค.
  • PL/SQL๊ณผ ์—ฐ๊ณ„: PL/SQL์—์„œ๋Š” SQL ์ปค์„œ๋ฅผ ์ž๋™์œผ๋กœ ์บ์‹ฑํ•œ๋‹ค. ๋‹จ, Oracle 10g๋ถ€ํ„ฐ๋Š” session_cached_cursors ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ 0๋ณด๋‹ค ํฐ ๊ฐ’์œผ๋กœ ์„ค์ •๋˜์–ด ์žˆ์–ด์•ผ ์ž‘๋™ํ•œ๋‹ค.

(5) ์žฅ์ 

  1. ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์บ์‹œ ๋ถ€ํ•˜ ๊ฒฝ๊ฐ: ์ž์ฃผ ์‹คํ–‰๋˜๋Š” SQL์— ์˜ํ•ด ๋ฐœ์ƒํ•˜๋Š” ๋ถ€ํ•˜๋ฅผ ์ค„์ธ๋‹ค.
  2. CPU ์‚ฌ์šฉ๋Ÿ‰ ๊ฐ์†Œ: SQL ๊ตฌ๋ฌธ ๋ถ„์„ ๋ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์บ์‹œ ํƒ์ƒ‰ ๊ณผ์ •์—์„œ ์†Œ๋ชจ๋˜๋Š” CPU ์ž์›์„ ์ค„์ธ๋‹ค.
  3. ๋ž˜์น˜ ์š”์ฒญ ํšŸ์ˆ˜ ๊ฐ์†Œ: ์†Œํ”„ํŠธ ํŒŒ์‹ฑ ๊ณผ์ •์—์„œ ๋ฐœ์ƒํ•˜๋Š” ๋ž˜์น˜ ์š”์ฒญ์„ ์ค„์—ฌ ์‹œ์Šคํ…œ ์„ฑ๋Šฅ์„ ํ–ฅ์ƒ์‹œํ‚จ๋‹ค.

 

๐Ÿ–‡๏ธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ปค์„œ ์บ์‹ฑ

๋ฌธ์ œ ๋ฐœ์ƒ

 

์„ธ์…˜ ์ปค์„œ๋ฅผ ์บ์‹ฑํ•˜๋ฉด SGA์˜ ๊ณต์œ  ์ปค์„œ๋ฅผ ๋น ๋ฅด๊ฒŒ ์ฐพ์•„ ์ปค์„œ๋ฅผ ์—ด ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜, ์„ธ์…˜ ์ปค์„œ ์บ์‹œ์— ์žˆ๋Š” SQL์„ ์‹คํ–‰ํ•˜๋”๋ผ๋„ ์—ฌ์ „ํžˆ ๊ณต์œ  ์ปค์„œ ํž™์„ Pin ํ•˜๊ณ , ์‹คํ–‰์— ํ•„์š”ํ•œ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์„ PGA์— ํ• ๋‹นํ•˜๋Š” ์ž‘์—…์€ ๋ฐ˜๋ณต๋œ๋‹ค.

์ด๋Ÿฌํ•œ ์ž‘์—…์„ ์ƒ๋žตํ•˜๊ณ  SQL์„ ๋”์šฑ ๋น ๋ฅด๊ฒŒ ์‹คํ–‰ํ•˜๋ ค๋ฉด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ปค์„œ ์บ์‹ฑ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค. ์ด ๊ธฐ๋Šฅ์€ ๊ณต์œ  ์ปค์„œ๋ฅผ Pin ํ•œ ์ƒํƒœ๋กœ ์œ ์ง€ํ•˜์—ฌ Parse Call์ด ์ตœ์ดˆ 1ํšŒ๋งŒ ๋ฐœ์ƒํ•˜๊ฒŒ ํ•œ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ๋Š” Execute Call ํšŸ์ˆ˜๋งŒํผ Parse Call์ด ๋ฐ˜๋ณต๋œ๋‹ค.

1. Java์—์„œ์˜ ์ปค์„œ ์บ์‹ฑ

Java์—์„œ ์ปค์„œ ์บ์‹ฑ์„ ์œ„ํ•ด ์•„๋ž˜ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•ด์•ผ ํ•œ๋‹ค:

  • ๋ฌต์‹œ์  ์บ์‹ฑ(implicit caching) ์˜ต์…˜์„ ํ™œ์„ฑํ™”ํ•˜๊ฑฐ๋‚˜, Statement(์ปค์„œ)๋ฅผ ๋‹ซ์ง€ ์•Š์•„์•ผ ํ•œ๋‹ค.
  • ํ•˜๋“œ ํŒŒ์‹ฑ์„ ์ตœ์ดˆ 1ํšŒ๋งŒ ์ˆ˜ํ–‰ํ•˜๋ ค๋ฉด ๋ฐ”์ธ๋“œ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

(1) ์ปค์„œ๋ฅผ ๋‹ซ์ง€ ์•Š๊ณ  ์žฌ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ

public static void CursorHolding (Connection conn, int count) throws Exception{
  PreparedStatement stmt = conn.prepareStatement ( 
  "SELECT /* cursor holding */ ?,?,?, a .* FROM emp a WHERE a.ename LIKE 'W%'");
  ResultSet rs;

  for (int i = 1; i <= count; i++) {

    stmt.setInt(1,i);
    stmt.setInt(2,i);
    stmt.setString(3,"test");
    rs=stmt.executeQuery();
    rs.close();

  }

  stmt.close(); // ๋ฃจํ”„ ์™ธ๋ถ€์—์„œ Cursor Close

}

 

๋ฐ”์ธ๋“œ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ–ˆ์œผ๋ฏ€๋กœ ํ•˜๋“œ ํŒŒ์‹ฑ์€ ์ตœ์ดˆ 1ํšŒ๋งŒ ์ˆ˜ํ–‰๋œ๋‹ค. ์ปค์„œ๋ฅผ ๋ฃจํ”„ ์™ธ๋ถ€์—์„œ ๋‹ซ์•„ ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋ฉฐ, Parse Call์€ 1ํšŒ๋งŒ ๋ฐœ์ƒํ•œ๋‹ค.

 

(2) ๋ฌต์‹œ์  ์บ์‹ฑ ๊ธฐ๋Šฅ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ

public static void CursorCaching(Connection conn, int count) throws Exception{
  ((OracleConnection) conn) .setStatementCacheSize(1); // ์บ์‹œ ์‚ฌ์ด์ฆˆ๋ฅผ 1๋กœ ์ง€์ •
  ((OracleConnection) conn) .setImplicitCachingEnabled(true); // ๋ฌต์‹œ์  ์บ์‹ฑ ๊ธฐ๋Šฅ ํ™œ์„ฑํ™”

  for (int i = 1; i <= count; i++) {
    PreparedStatement stmt = conn.prepareStatement (
    "SELECT /* implicit caching */ ?,?,?,a .* " +
    "FROM emp a WHERE a.ename LIKE 'W%'");
    stmt.setInt(1,i);
    stmt.setInt(2,i);
    stmt.setString(3,"test");
    ResultSet rs=stmt.executeQuery();

    rs.close();

    stmt.close(); // ๋ฃจํ”„ ๋‚ด๋ถ€์—์„œ Cursor Close
  }
}

 

์ปค์„œ๋ฅผ ๋ฃจํ”„ ๋‚ด๋ถ€์—์„œ ๋‹ซ๋”๋ผ๋„ ๋ฌต์‹œ์  ์บ์‹ฑ ์˜ต์…˜์ด ํ™œ์„ฑํ™”๋˜์–ด ๋‚ด๋ถ€์ ์œผ๋กœ ์บ์‹œ์— ์ €์žฅ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ปค์„œ๋ฅผ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋Š” ๋ฌต์‹œ์  ์บ์‹ฑ ์˜ต์…˜์„ ํ™œ์„ฑํ™”ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

2. PL/SQL์—์„œ์˜ ์ปค์„œ ์บ์‹ฑ

PL/SQL์—์„œ๋Š” ๋ณ„๋„์˜ ์˜ต์…˜ ์—†์ด๋„ ์ž๋™์œผ๋กœ ์ปค์„œ๋ฅผ ์บ์‹ฑํ•œ๋‹ค. ๋‹จ, Static SQL์ผ ๊ฒฝ์šฐ์—๋งŒ ์บ์‹ฑ์ด ์ ์šฉ๋˜๋ฉฐ, Dynamic SQL์ด๋‚˜ Cursor Variable(Ref Cursor)์„ ์‚ฌ์šฉํ•˜๋ฉด ์ž๋™ ์บ์‹ฑ ํšจ๊ณผ๊ฐ€ ์‚ฌ๋ผ์ง„๋‹ค.

  • Oracle 9i๊นŒ์ง€๋Š” open_cursors ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ ์บ์‹ฑ ๊ฐ€๋Šฅํ•œ SQL ๊ฐœ์ˆ˜๋ฅผ ๊ฒฐ์ •ํ–ˆ๋‹ค.
  • Oracle 10g๋ถ€ํ„ฐ๋Š” session_cached_cursors ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ ์ด๋ฅผ ๋Œ€์‹ ํ•œ๋‹ค. ํ•ด๋‹น ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” ์„ธ์…˜ ์ปค์„œ๊ณผ๋„ ๊ด€๋ จ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์„ธ์…˜ ์ปค์„œ ์บ์‹ฑ ๊ธฐ๋Šฅ์ด ๋น„ํ™œ์„ฑํ™”๋˜๋ฉด PL/SQL์˜ ์ž๋™ ์ปค์„œ ์บ์‹ฑ๋„ ๋น„ํ™œ์„ฑํ™”๋œ๋‹ค.

3. n-Tier ํ™˜๊ฒฝ์—์„œ์˜ ์ปค์„œ ์บ์‹ฑ

n-Tier ํ™˜๊ฒฝ์—์„œ๋Š” DB Connection ์‚ฌ์šฉ ํ›„ ์ฆ‰์‹œ ์ปค๋„ฅ์…˜ ํ’€์— ๋ฐ˜ํ™˜๋˜๋ฏ€๋กœ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ˆ˜์ค€์—์„œ ์ปค์„œ ์บ์‹ฑ ๊ธฐ๋ฒ•์„ ํšจ๊ณผ์ ์œผ๋กœ ํ™œ์šฉํ•˜๊ธฐ ์–ด๋ ต๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ PL/SQL๋กœ ์ž‘์„ฑ๋œ ํ•จ์ˆ˜๋‚˜ ํ”„๋กœ์‹œ์ €๋ฅผ ์ ๊ทน์ ์œผ๋กœ ํ™œ์šฉํ•˜๋ฉด, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ปค์„œ ์บ์‹ฑ๊ธฐ๋ฒ•์„ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด ์ ‘๊ทผ ๋ฐฉ์‹์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์บ์‹œ ํšจ์œจ์„ ํฌ๊ฒŒ ํ–ฅ์ƒ์‹œํ‚จ๋‹ค.

๐Ÿ–‡๏ธ Static SQL vs Dynamic SQL

Static SQL (=Embedded SQL) ์ด๋ž€? ๋ฌธ์ž์—ด ๋ณ€์ˆ˜์— ๋‹ด์ง€ ์•Š๊ณ  ์ฝ”๋“œ ์‚ฌ์ด์— ์ง์ ‘ ๊ธฐ์ˆ ๋œ SQL๋ฌธ์„ ์˜๋ฏธํ•œ๋‹ค.

  • Static SQL์„ ์ง€์›ํ•˜๋Š” ๊ฐœ๋ฐœ ์–ธ์–ด๋Š” PowerBuilder, PL/SQL, Proc*C, SQLJ ๋ฟ์ด๊ณ  ์ด์™ธ์—๋Š” ๋ชจ๋‘ Dynamic SQL์„ ์ง€์›ํ•œ๋‹ค.

Dynamic SQL ์ด๋ž€? ๋ฌธ์ž์—ด ๋ณ€์ˆ˜์— ๋‹ด์•„์„œ ๊ธฐ์ˆ ํ•˜๋Š” SQL๋ฌธ์„ ์˜๋ฏธํ•œ๋‹ค.

  • ๋ณ€์ˆ˜์˜ ๊ฐ’์„ ๋™์ ์œผ๋กœ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์กฐ๊ฑด์— ๋”ฐ๋ผ SQL๋ฌธ์„ ์œ ์—ฐํ•˜๊ฒŒ ์กฐ์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์‹คํ–‰ ์‹œ ์‚ฌ์šฉ์ž ์ž…๋ ฅ์„ ๋ฐ›์•„ SQL๋ฌธ์˜ ์ผ๋ถ€ ๋˜๋Š” ์ „์ฒด๋ฅผ ๊ตฌ์„ฑํ•˜์—ฌ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

์„ฑ๋Šฅ๊ณผ ๋ฐ”์ธ๋“œ ๋ณ€์ˆ˜ ์‚ฌ์šฉ

Static SQL๊ณผ Dynamic SQL์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐœ๋ฐœ ๊ด€์ ์—์„œ์˜ ๊ตฌ๋ถ„์ผ ๋ฟ, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ž…์žฅ์—์„œ๋Š” ๋™์ผํ•œ SQL๋ฌธ์œผ๋กœ ์ฒ˜๋ฆฌ๋œ๋‹ค. ๋”ฐ๋ผ์„œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ปค์„œ ์บ์‹ฑ ๊ธฐ๋Šฅ์„ ํ™œ์šฉํ•˜์ง€ ์•Š๋Š” ํ•œ, Static, Dynamic ๊ตฌ๋ถ„์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์บ์‹œ ํšจ์œจ์— ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š๋Š”๋‹ค.

 

๊ฒฐ๊ตญ, ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์บ์‹œ ํšจ์œจ์„ ๋…ผํ•  ๋•Œ ์ดˆ์ ์€ ๋ฐ”์ธ๋“œ ๋ณ€์ˆ˜ ์‚ฌ์šฉ ์—ฌ๋ถ€์— ๋งž์ถฐ์ ธ์•ผ ํ•œ๋‹ค. Dynamic SQL์˜ ์‚ฌ์šฉ ์ž์ฒด๊ฐ€ ์„ฑ๋Šฅ ๋ฌธ์ œ๋ฅผ ์œ ๋ฐœํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, ๋ฐ”์ธ๋“œ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์„ ๋•Œ ๋ฌธ์ œ๊ฐ€ ๋˜๋Š” ๊ฒƒ์ด๋‹ค.

 

๋”ฐ๋ผ์„œ SQL ์„ฑ๋Šฅ ์ตœ์ ํ™”๋ฅผ ์œ„ํ•ด์„œ๋Š” Static, Dynamic ๊ตฌ๋ถ„๋ณด๋‹ค ๋ฐ”์ธ๋“œ ๋ณ€์ˆ˜๋ฅผ ์ ์ ˆํžˆ ํ™œ์šฉํ•˜๋Š” ๊ฒƒ์— ์ดˆ์ ์„ ๋งž์ถ”๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•˜๋‹ค. Static๊ณผ Dynamic SQL์„ ๋ฐ”์ธ๋“œ ๋ณ€์ˆ˜ ์‚ฌ์šฉ ์—ฌ๋ถ€๋กœ ๊ตฌ๋ถ„ํ•˜๋ ค๋Š” ๊ฒƒ์€ ์ ์ ˆํ•˜์ง€ ์•Š๋‹ค.

1. Dynamic SQL ์‚ฌ์šฉ ๊ธฐ์ค€

(1) Dynamic SQL ์‚ฌ์šฉ์— ๊ด€ํ•œ ๊ธฐ๋ณธ ์›์น™

  1. Static SQL์„ ์ง€์›ํ•˜๋Š” ๊ฐœ๋ฐœํ™˜๊ฒฝ์ด๋ผ๋ฉด, Static SQL๋กœ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์ด ์›์น™์œผ๋กœ ํ•œ๋‹ค.
    • ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์บ์‹ฑ ๊ธฐ๋Šฅ์ด ํ•„์š”ํ•œ ์ƒํ™ฉ์—์„œ Dynamic SQL์„ ์‚ฌ์šฉํ•˜๋ฉด ์„ฑ๋Šฅ์ด ์ €ํ•˜๋  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
  2. Dynamic SQL ์‚ฌ์šฉ์ด ํ—ˆ์šฉ๋˜๋Š” ๊ฒฝ์šฐ
    • PreCompile ๊ณผ์ •์—์„œ ์ปดํŒŒ์ผ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” SQL ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•  ๋•Œ (์˜ˆ: ์Šค์นผ๋ผ ์„œ๋ธŒ์ฟผ๋ฆฌ, ๋ถ„์„ ํ•จ์ˆ˜, ANSI ์กฐ์ธ ๋“ฑ).
    • ์ƒํ™ฉ๊ณผ ์กฐ๊ฑด์— ๋”ฐ๋ผ ์ƒ์„ฑ๋˜๋Š” SQL์˜ ๊ฒฝ์šฐ์˜ ์ˆ˜๊ฐ€ ๋„ˆ๋ฌด ๋งŽ์•„ Static SQL๋กœ ์ž‘์„ฑํ•˜๋ฉด ๊ฐœ๋ฐœ ์ƒ์‚ฐ์„ฑ์ด ๋–จ์–ด์ง€๊ณ  ์œ ์ง€๋ณด์ˆ˜ ๋น„์šฉ์ด ํฌ๊ฒŒ ์ฆ๊ฐ€ํ•˜๋Š” ๊ฒฝ์šฐ.
  3. Dynamic SQL์„ ์‚ฌ์šฉํ•  ๋•Œ๋„ ์กฐ๊ฑด์ ˆ์—๋Š” ๋ฐ”์ธ๋“œ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ์›์น™์œผ๋กœ ํ•œ๋‹ค.
    • ํŠนํžˆ ์‚ฌ์šฉ ๋นˆ๋„๊ฐ€ ๋†’๊ณ  ์กฐ๊ฑด์ ˆ์˜ ์ปฌ๋Ÿผ ๊ฐ’ ์ข…๋ฅ˜๊ฐ€ ๋งŽ์€ ๊ฒฝ์šฐ์—๋Š” ๋ฐ˜๋“œ์‹œ ์ค€์ˆ˜ํ•ด์•ผ ํ•œ๋‹ค.
  4. ๋ฐ”์ธ๋“œ ๋ณ€์ˆ˜ ๋ฏธ์‚ฌ์šฉ์ด ์˜ˆ์™ธ์ ์œผ๋กœ ์ธ์ •๋˜๋Š” ๊ฒฝ์šฐ → [[#(4) ์˜ˆ์™ธ์ ์œผ๋กœ, Literal ์ƒ์ˆ˜๊ฐ’ ์‚ฌ์šฉ|Literal ์ƒ์ˆ˜๊ฐ’ ์‚ฌ์šฉ]]
    • Long Running ์ฟผ๋ฆฌ: ๋ฐฐ์น˜ ํ”„๋กœ๊ทธ๋žจ, DW, OLAP ๋“ฑ ์ •๋ณด๊ณ„ ์‹œ์Šคํ…œ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ์ฟผ๋ฆฌ๋กœ, ํŒŒ์‹ฑ ์†Œ์š” ์‹œ๊ฐ„์ด ์ „์ฒด ์ฟผ๋ฆฌ ์ˆ˜ํ–‰ ์‹œ๊ฐ„์—์„œ ์ฐจ์ง€ํ•˜๋Š” ๋น„์ค‘์ด ๋งค์šฐ ๋‚ฎ๊ณ , ์ˆ˜ํ–‰ ๋นˆ๋„๋„ ๋‚ฎ์•„ ํ•˜๋“œํŒŒ์‹ฑ์— ์˜ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์บ์‹œ ๋ถ€ํ•˜๋ฅผ ์œ ๋ฐœํ•  ๊ฐ€๋Šฅ์„ฑ์ด ์ ์€ ๊ฒฝ์šฐ.
    • OLTP ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ์˜ ์˜ˆ์™ธ: ์‚ฌ์šฉ ๋นˆ๋„๊ฐ€ ๋งค์šฐ ๋‚ฎ์•„ ํ•˜๋“œํŒŒ์‹ฑ์œผ๋กœ ์ธํ•œ ๋ถ€ํ•˜ ๊ฐ€๋Šฅ์„ฑ์ด ์—†๋Š” ๊ฒฝ์šฐ ์˜ˆ์™ธ์ ์œผ๋กœ ํ—ˆ์šฉ๋œ๋‹ค. ๋‹ค๋งŒ, OLTP ํ™˜๊ฒฝ์—์„œ๋Š” ๊ฐ€๋Šฅํ•˜๋ฉด ๋ฐ”์ธ๋“œ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์›์น™์ด๋‹ค.
    • ์กฐ๊ฑด์ ˆ ๊ฐ’์˜ ์ข…๋ฅ˜๊ฐ€ ์†Œ์ˆ˜์ด๋ฉฐ, ๊ฐ’ ๋ถ„ํฌ๊ฐ€ ๊ท ์ผํ•˜์ง€ ์•Š์•„ ์˜ตํ‹ฐ๋งˆ์ด์ €๊ฐ€ ์ปฌ๋Ÿผ ํžˆ์Šคํ† ๊ทธ๋žจ ์ •๋ณด๋ฅผ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์œ ๋„ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ.

(2) Static SQL์˜ ์„ ํƒ์  ๊ฒ€์ƒ‰ ์กฐ๊ฑด

Dynamic SQL ์‚ฌ์šฉ ์›์น™์„ ์ •ํ•ด๋„ ์‹ค์ œ ๊ฐœ๋ฐœ์—์„œ๋Š” ์ œ๋Œ€๋กœ ์ง€์ผœ์ง€๊ธฐ ์–ด๋ ค์šด ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๋‹ค. ํŠนํžˆ ๊ฒ€์ƒ‰ ์กฐ๊ฑด์ด ๋‹ค์–‘ํ•ด ์‚ฌ์šฉ์ž ์„ ํƒ์— ๋”ฐ๋ผ ์กฐ๊ฑด์ ˆ์ด ๋™์ ์œผ๋กœ ๋ฐ”๋€Œ๋Š” ์ƒํ™ฉ์—์„œ๋Š” Static SQL๋งŒ์œผ๋กœ ๋Œ€์‘ํ•˜๊ธฐ ์–ด๋ ต๋‹ค.

 

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

 

๋ฌธ์ œ์  : ์กฐ๊ฑด์ ˆ ์ปฌ๋Ÿผ์ด ์ธ๋ฑ์Šค์ธ ๊ฒฝ์šฐ, ์ธ๋ฑ์Šค๋ฅผ ์ „ํ˜€ ์‚ฌ์šฉํ•˜์ง€ ๋ชปํ•˜๊ฑฐ๋‚˜ ๋น„ํšจ์œจ์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.

 

์˜ˆ์‹œ ์ฝ”๋“œ :

SELECT *
FROM TABLE
WHERE ์ผ์ž BETWEEN :ST AND :ET
AND ๊ตฌ๋ถ„ = NVL(:GUBUN, 'GUBUN')
AND ์œ ํ˜• = NVL(:CODE, 'CODE')

 

์ด์ฒ˜๋Ÿผ NVL์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์บ์‹œ ํšจ์œจ์€ ๋†’์•„์ง€์ง€๋งŒ, I/O ํšจ์œจ์€ ์ €ํ•˜๋  ์ˆ˜ ์žˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ฒฝ์šฐ ํ˜„์‹ค์ ์ธ ๋Œ€์•ˆ์ด ํ•„์š”ํ•˜๋‹ค.

 

ํ˜„์‹ค์ ์ธ ๋Œ€์•ˆ :

  1. Static SQL ์‚ฌ์šฉ ์›์น™ ์ค€์ˆ˜:
    ์‚ฌ์šฉ์ž ์ž…๋ ฅ ์กฐ๊ฑด์— ๋”ฐ๋ผ ์ƒ์„ฑ๋  ์ˆ˜ ์žˆ๋Š” SQL ๊ฐœ์ˆ˜๊ฐ€ ๋„ˆ๋ฌด ๋งŽ์„ ๊ฒฝ์šฐ, Dynamic SQL ์‚ฌ์šฉ์„ ํ—ˆ์šฉํ•œ๋‹ค.
    • Dynamic SQL๋กœ ์ƒ์„ฑ๋œ SQL ์ค‘ ์ผ๋ถ€๋งŒ ์ž์ฃผ ์‚ฌ์šฉ๋˜๊ธฐ ๋•Œ๋ฌธ์—, ์‹ค์งˆ์ ์ธ ํ•˜๋“œํŒŒ์‹ฑ ๋ถ€ํ•˜๋Š” ํฌ์ง€ ์•Š๋‹ค.
    • ๋‹ค๋งŒ, ๋ฐ”์ธ๋“œ ๋ณ€์ˆ˜ ์‚ฌ์šฉ ์›์น™์€ ๋ฐ˜๋“œ์‹œ ์ค€์ˆ˜ํ•ด์•ผ ํ•œ๋‹ค.
  2. Dynamic SQL์˜ ๋‹จ์ :
    • ์กฐ๊ฑด์ ˆ์ด ๋™์ ์œผ๋กœ ๋ณ€๊ฒฝ๋˜์–ด ์ธ๋ฑ์Šค ์„ค๊ณ„๊ฐ€ ์–ด๋ ค์›Œ์งˆ ์ˆ˜ ์žˆ๋‹ค.
    • ์˜ตํ‹ฐ๋งˆ์ด์ € ํžŒํŠธ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•  ๊ฒฝ์šฐ, SQL์ด ๋™์ ์œผ๋กœ ๋ณ€๊ฒฝ๋˜๋ฉด ํžŒํŠธ ์ ์šฉ์ด ์–ด๋ ต๋‹ค.
  3. ๊ฒฐ๋ก :
    ๊ฐœ๋ฐœ ์ƒ์‚ฐ์„ฑ๊ณผ ์„ฑ๋Šฅ์„ ๋ชจ๋‘ ๊ณ ๋ คํ•ด Static SQL ์‚ฌ์šฉ์„ ๊ธฐ๋ณธ ์›์น™์œผ๋กœ ํ•˜๊ณ , Dynamic SQL์€ ์‹ ์ค‘ํ•˜๊ฒŒ ํ•„์š”ํ•  ๋•Œ๋งŒ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

 

์„ ํƒ์  ๊ฒ€์ƒ‰ ์กฐ๊ฑด ์‹œ Static SQL ํ™œ์šฉ ๋ฐฉ์•ˆ

 

๋‹ค์–‘ํ•œ ๊ฒ€์ƒ‰ ์กฐ๊ฑด์„ ์ฒ˜๋ฆฌํ•  ๋•Œ๋Š” ์•„๋ž˜ ๋ฐฉ๋ฒ•๋“ค์„ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ฐ ๋ฐฉ๋ฒ•์˜ ์žฅ๋‹จ์ ์„ ์ดํ•ดํ•˜๊ณ  ์ ์ ˆํžˆ ์„ ํƒํ•ด์•ผ ํ•œ๋‹ค.

  1. (:CODE IS NULL OR CODE = :CODE)
    • ๋‹จ์ : OR ์กฐ๊ฑด์ด ํฌํ•จ๋˜๋ฉด TABLE FULL SCAN์ด ๋ฐœ์ƒํ•œ๋‹ค. ์ธ๋ฑ์Šค๋ฅผ ํ™œ์šฉํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” ์ ํ•ฉํ•˜์ง€ ์•Š๋‹ค.
  2. CODE LIKE :CODE || '%'
    • ์žฅ์ : ์ธ๋ฑ์Šค ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
    • ๋‹จ์ :
      • ์‚ฌ์šฉ์ž๊ฐ€ ๊ฐ’์„ ์ž…๋ ฅํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ์—๋„ ์ธ๋ฑ์Šค๋ฅผ ์‚ฌ์šฉํ•ด ์„ฑ๋Šฅ์ด ์ €ํ•˜๋  ์ˆ˜ ์žˆ๋‹ค.
      • NULL ํ—ˆ์šฉ ์ปฌ๋Ÿผ์ผ ๋•Œ๋Š” ๊ฒฐ๊ณผ ์ง‘ํ•ฉ์ด ๋‹ฌ๋ผ์งˆ ์ˆ˜ ์žˆ๋‹ค.
  3. ์กฐ๊ฑด์ ˆ = NVL(:CODE, 'CODE') / ์กฐ๊ฑด์ ˆ = DECODE(:CODE, NULL, 'CODE', :CODE)
    • ์žฅ์ : ๋ณ€์ˆ˜ ์ž…๋ ฅ ์—ฌ๋ถ€์— ๋”ฐ๋ผ TABLE FULL SCAN๊ณผ INDEX SCAN์œผ๋กœ ์‹คํ–‰ ๊ณ„ํš์ด ๋ถ„๊ธฐ๋œ๋‹ค.
    • ๋‹จ์ :
      • NULL ํ—ˆ์šฉ ์ปฌ๋Ÿผ์—์„œ๋Š” ๊ฒฐ๊ณผ ์ง‘ํ•ฉ์ด ๋‹ฌ๋ผ์งˆ ์ˆ˜ ์žˆ๋‹ค.
      • ์—ฌ๋Ÿฌ ์ปฌ๋Ÿผ์— ๋Œ€ํ•œ ์‚ฌ์šฉํ•  ๋•Œ๋Š” ๊ทธ์ค‘ ๋ณ€๋ณ„๋ ฅ์ด ๊ฐ€์žฅ ์ข‹์€ ์ปฌ๋Ÿผ ๊ธฐ์ค€์œผ๋กœ ํ•œ๋ฒˆ๋งŒ ๋ถ„๊ธฐ๊ฐ€ ์ผ์–ด๋‚œ๋‹ค. ์ด๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ๋ณต์žกํ•œ ์˜ต์…˜ ์กฐ๊ฑด์„ ์ฒ˜๋ฆฌํ•  ๋•Œ, ์ด ๋ฐฉ์‹์—๋งŒ ์˜์กดํ•˜๊ธฐ ์–ด๋ ต๋‹ค.
  4. UNION ALL ์‚ฌ์šฉ: ์กฐ๊ฑด์— ๋”ฐ๋ผ ์ฟผ๋ฆฌ๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ๋ถ„๊ธฐ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.
    • ์žฅ์ : ๋ช…ํ™•ํ•œ ์‹คํ–‰ ๊ณ„ํš์œผ๋กœ ์ธ๋ฑ์Šค ํ™œ์šฉ์ด ์šฉ์ดํ•˜๋‹ค.

์„ ํƒ ๊ธฐ์ค€ :

  • NOT NULL ์ปฌ๋Ÿผ : NVL/DECODE๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ํŽธ๋ฆฌํ•˜๋‹ค.
  • NULL ํ—ˆ์šฉ ์ปฌ๋Ÿผ : ์ธ๋ฑ์Šค ์•ก์„ธ์Šค๊ฐ€ ์ค‘์š”ํ•œ ๊ฒฝ์šฐ, UNION ALL์„ ์‚ฌ์šฉํ•ด ๋ช…์‹œ์ ์œผ๋กœ ๋ถ„๊ธฐ ์ฒ˜๋ฆฌํ•œ๋‹ค.
  • ์ธ๋ฑ์Šค ์•ก์„ธ์Šค๊ฐ€ ํ•„์š” ์—†๋Š” ๊ฒฝ์šฐ : ์ธ๋ฑ์Šค ํ•„ํ„ฐ ๋˜๋Š” ํ…Œ์ด๋ธ” ํ•„ํ„ฐ ์กฐ๊ฑด์œผ๋กœ๋งŒ ์‚ฌ์šฉ๋˜๋Š” ์ปฌ๋Ÿผ์€ ์–ด๋–ค ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•ด๋„ ๋ฌด๋ฐฉํ•˜๋‹ค.

2. Static SQL ๊ตฌํ˜„์„ ์œ„ํ•œ ๊ธฐ๋ฒ•๋“ค

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

(1) IN-List ํ•ญ๋ชฉ์ด ๊ฐ€๋ณ€์ ์ด์ง€๋งŒ ์ตœ๋Œ€ ๊ฒฝ์šฐ ์ˆ˜๊ฐ€ ์ ์€ ๊ฒฝ์šฐ

๋ชจ๋“  ๊ฒฝ์šฐ์˜ ์ˆ˜๋ฅผ SQL๋กœ ์ž‘์„ฑํ•˜๊ธฐ ์–ด๋ ค์šด ๊ฒฝ์šฐ, ์ตœ๋Œ€ ๊ฐœ์ˆ˜๋งŒํผ ๋ฐ”์ธ๋“œ ๋ณ€์ˆ˜๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ์‹์ด ์žˆ๋‹ค.

SELECT * FROM TABLE WHERE COL IN (:A, :B, :C);
  • ์ž…๋ ฅํ•˜์ง€ ์•Š์€ ํ•ญ๋ชฉ์—๋Š” NULL ๊ฐ’์„ ์ž…๋ ฅํ•˜๋ฉด ๊ฒฐ๊ณผ ์ง‘ํ•ฉ์—์„œ ์ž๋™์œผ๋กœ ์ œ์™ธ๋œ๋‹ค.
  • ์ „์ฒด ์กฐํšŒ๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ, DECODE ๋ฌธ์„ ํ™œ์šฉํ•œ๋‹ค
SELECT * FROM TABLE WHERE COL IN ( DECODE(:A, 'ALL'),'01',:A),
                                   DECODE(:B, 'ALL'),'02',:B),
                                   DECODE(:C, 'ALL'),'03',:C),);

(2) IN-List ํ•ญ๋ชฉ์ด ๊ฐ€๋ณ€์ ์ด์ง€๋งŒ ์ตœ๋Œ€ ๊ฒฝ์šฐ ์ˆ˜๊ฐ€ ๋งŽ์€ ๊ฒฝ์šฐ

๊ฒฝ์šฐ์˜ ์ˆ˜๊ฐ€ ๋งŽ์€ ์ƒํ™ฉ์—์„œ๋Š” IN ์กฐ๊ฑด์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์–ด๋ ค์šด ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค. ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์ปฌ๋Ÿผ๊ณผ ๋ณ€์ˆ˜ ์œ„์น˜๋ฅผ ๋ฐ”๊พธ๋Š” ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ๋ฌธ์ž์—ด์„ ์ฒ˜๋ฆฌํ•˜๋Š” ์˜ค๋ผํด ๋‚ด๋ถ€ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์ƒ LIKE ์—ฐ์‚ฐ์ž ๋ณด๋‹ค INSTR ํ•จ์ˆ˜๊ฐ€ ๋” ๋น ๋ฅด๊ธฐ ๋•Œ๋ฌธ์— ์•„๋ž˜์™€ ๊ฐ™์ด ์ž‘์„ฑํ•˜์˜€๋‹ค.

:LIST := '01,02,03,....,30'

SELECT *
FROM ์ด๋ ฅ
WHERE INSTR(:LIST, CODE) > 0
AND   GUBUN = :B

 

๋ฌธ์ œ์ :

  • LIKE๋‚˜ INSTR์€ ์ปฌ๋Ÿผ์„ ๊ฐ€๊ณตํ•œ ํ˜•ํƒœ๋กœ ์‚ฌ์šฉ๋˜๋ฏ€๋กœ, ์ธ๋ฑ์Šค ์•ก์„ธ์Šค ์กฐ๊ฑด์œผ๋กœ ํ™œ์šฉํ•˜์ง€ ๋ชปํ•œ๋‹ค.
  • CODE ์ปฌ๋Ÿผ์ด ์„ ๋‘ ์ปฌ๋Ÿผ์ธ ์ธ๋ฑ์Šค์—์„œ๋Š” ์ธ๋ฑ์Šค ํšจ์œจ์ด ๋–จ์–ด์งˆ ์ˆ˜ ์žˆ๋‹ค.

ํ•ด๊ฒฐ ๋ฐฉ์•ˆ:

  • ์ธ๋ฑ์Šค ๊ตฌ์„ฑ [CODE + GUBUN]์ธ ๊ฒฝ์šฐ : LIKE๋‚˜ INSTR์€ ์ปฌ๋Ÿผ ์‚ฌ์šฉ ์‹œ, ์„ ๋‘ ์ปฌ๋Ÿผ์ด ๊ฐ€๊ณตํ•œ ํ˜•ํƒœ ์ด๋ฏ€๋กœ ์ธ๋ฑ์Šค๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ๋ชปํ•˜๊ฑฐ๋‚˜ Index Full Scan ์ฒ˜๋ฆฌํ•ด์•ผ ํ•˜๋ฏ€๋กœ IN ์—ฐ์‚ฐ์ž๊ฐ€ ๋” ์œ ๋ฆฌํ•˜๋‹ค.
  • ์ธ๋ฑ์Šค ๊ตฌ์„ฑ [GUBUN + CODE]์ธ ๊ฒฝ์šฐ :
    • CODE ํ•ญ๋ชฉ ๊ฐœ์ˆ˜๊ฐ€ ์†Œ์ˆ˜์ธ ๊ฒฝ์šฐ, IN ์—ฐ์‚ฐ์ž๊ฐ€ ์œ ๋ฆฌํ•˜๋‹ค.
    • CODE ํ•ญ๋ชฉ ๊ฐœ์ˆ˜๊ฐ€ ๋‹ค์ˆ˜์ธ ๊ฒฝ์šฐ, ์ธ๋ฑ์Šค๋ฅผ ๊ทธ๋งŒํผ ์—ฌ๋Ÿฌ ๋ฒˆ ํƒ์นจ ํ•ด์•ผ๋งŒ ํ•œ๋‹ค. INSTR/ LIKE ๊ตฌ๋ฌธ์„ ํ†ตํ•ด ์ธ๋ฑ์Šค ํ•„ํ„ฐ ์กฐ๊ฑด์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋” ์œ ๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

์ธ๋ฑ์Šค ๊ตฌ์„ฑ [GUBUN + CODE] ์ผ ๋•Œ, ์ธ๋ฑ์Šค๋ฅผ ์ข€ ๋” ํšจ์œจ์ ์œผ๋กœ ์•ก์„ธ์Šค ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•

 

โ‘  Nested Loop Join ํ™œ์šฉ :

:LIST := '01,02,03,....,30'

SELECT /*+ ORDERED USE_NL(B) */ B.*
FROM (
    SELECT CODE
    FROM ์ด๋ ฅ ์ฝ”๋“œ
    WHERE INSTR(:LIST, CODE) > 0
) A, ์ด๋ ฅ B
ON  B.CODE = A.CODE
AND B.GUBUN = :B

 

์ด๋ ฅ ์ฝ”๋“œ ํ…Œ์ด๋ธ”์„ Full Scan ํ•˜๋ฉด์„œ NL ์กฐ์ธ ๋ฐฉ์‹์œผ๋กœ CODE ๊ฐ’์„ ์ด๋ ฅ ํ…Œ์ด๋ธ”์— ๋˜์ ธ์ฃผ๊ธฐ ๋•Œ๋ฌธ์— ์ธ๋ฑ์Šค๋ฅผ ์ •์ƒ์ ์œผ๋กœ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ๋‹จ, ์ด๋ ฅ ์ฝ”๋“œ ํ…Œ์ด๋ธ”์„ Full Scan ํ•  ๋•Œ, ๋น„ํšจ์œจ์ด ์—†์–ด์•ผ ํ•œ๋‹ค.

 

โ‘ก SUBSTR๋กœ ์ฝ”๋“œ ์ƒ์„ฑ :

:LIST := '01,02,03,....,30'

SELECT /*+ ORDERED USE_NL(B) */ B.*
FROM (
    SELECT SUBSTR(:LIST, (LEVEL - 1) * 2 + 1, 2) AS CODE
    FROM DUAL
    CONNECT BY LEVEL <= LENGTH(:LIST) / 2
) A, ์ด๋ ฅ B
ON  B.CODE = A.CODE
AND B.GUBUN = :B

 

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

(3) ์ฒดํฌ ์กฐ๊ฑด์ด ๊ฐ€๋ณ€์ ์ธ ๊ฒฝ์šฐ

DECODE ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋™์ ์œผ๋กœ ์กฐ๊ฑด์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

SELECT COL, SUM(NUM)
FROM ์ด๋ ฅ A
WHERE DATE = :DATE
AND   GUBUN = :GUBUN
AND EXISTS (
    SELECT '1'
    FROM ์ด๋ ฅ์ฝ”๋“œ
    WHERE CODE = A.CODE
    AND   CHK = DECODE(:YN, 'Y', 'Y', CHK)
)
GROUP BY COL

 

๋ฌธ์ œ์ :

  • ์ง‘๊ณ„ ์กฐ๊ฑด์ด ์ „์ฒด๋ฅผ ๋Œ€์ƒ์œผ๋กœ ํ™•์žฅ๋  ๋•Œ, ๋ถˆํ•„์š”ํ•œ ์„œ๋ธŒ์ฟผ๋ฆฌ๋ฅผ ์ˆ˜ํ–‰ํ•จ์œผ๋กœ์จ ๋ธ”๋ก I/O๊ฐ€ ์ฆ๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์กฐ๊ฑด์— ๋”ฐ๋ผ SQL์„ ๋ถ„๋ฆฌํ•˜๊ฑฐ๋‚˜ UNION ALL์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋” ๋‚˜์€ ์„ ํƒ์ผ ์ˆ˜ ์žˆ๋‹ค.

๋Œ€์•ˆ:

SELECT COL, SUM(NUM)
FROM ์ด๋ ฅ A
WHERE DATE = :DATE
AND   GUBUN = :GUBUN
AND EXISTS (
    SELECT '1'
    FROM DUAL
    WHERE :YN = 'N'
    UNION ALL
    SELECT '1'
    FROM ์ด๋ ฅ์ฝ”๋“œ
    WHERE CODE = A.CODE
    AND   CHK = 'Y'
    AND   :YN = 'Y'
)
GROUP BY COL

 

EXISTS ์„œ๋ธŒ์ฟผ๋ฆฌ๋Š” ์กฐ๊ฑด์— ๋ถ€ํ•ฉํ•˜๋Š” ์ฒซ ๋ฒˆ์งธ ๋ ˆ์ฝ”๋“œ๋ฅผ ์ฐพ์œผ๋ฉด ์ฆ‰์‹œ true๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ  ์‹คํ–‰์„ ์ข…๋ฃŒํ•œ๋‹ค. ํŠนํžˆ 10g ์ดํ›„๋ถ€ํ„ฐ๋Š” DUAL ํ…Œ์ด๋ธ”์ด FAST DUAL ๋ฐฉ์‹์œผ๋กœ ์ตœ์ ํ™”๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ธ”๋ก I/O๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š”๋‹ค.

 

9i์—์„œ๋Š” DUAL ํ…Œ์ด๋ธ”์„ Full Scan ๋ฐฉ์‹์œผ๋กœ ์ฝ๊ฒŒ ๋˜๋ฏ€๋กœ, ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฌธ์ œ์ ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค. ํ•„ํ„ฐ ์บ์‹ฑ ํšจ๊ณผ๊ฐ€ ์žˆ์ง€๋งŒ, ์ตœ์†Œ DATE, GUBUN ์กฐ๊ฑด ๊ฒฐ๊ณผ ๊ฑด์ˆ˜์— ๋”ฐ๋ผ DUAL ํ…Œ์ด๋ธ”์„ ๋ฐ˜๋ณต์ ์œผ๋กœ ์ฝ์–ด์•ผ ํ•œ๋‹ค. ๋ฐ˜๋ณต์ ์œผ๋กœ ์ฝ๋Š” ๊ณผ์ •์—์„œ ์„ธ๊ทธ๋จผํŠธ ํ—ค๋” ํฌํ•จ 2~4๊ฐœ ๋ธ”๋ก I/O๊ฐ€ ์ถ”๊ฐ€๋กœ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.

(4) SELECT-LIST๊ฐ€ ๋™์ ์œผ๋กœ ๋ฐ”๋€Œ๋Š” ๊ฒฝ์šฐ

DECODE๋‚˜ CASE ํ•จ์ˆ˜๋ฅผ ํ™œ์šฉํ•˜์—ฌ SELECT-LIST๋ฅผ ๋™์ ์œผ๋กœ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค.

DECODE(:GUBUN, '01', SUM(QTY), AVG(AMT)) AS NUM

 

๋ฌธ์ œ์  : ์ง‘๊ณ„ ํ•จ์ˆ˜ ๋‚ด๋ถ€์— DECODE๋‚˜ CASE ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด, ๋ฐ˜๋ณต ์ˆ˜ํ–‰๋˜์–ด ์„ฑ๋Šฅ์ด ์ €ํ•˜๋  ์ˆ˜ ์žˆ๋‹ค.

SUM(DECODE(:GUBUN, '01', QTY, AMT)) AS NUM

(5) ์—ฐ์‚ฐ์ž๊ฐ€ ๋ฐ”๋€Œ๋Š” ๊ฒฝ์šฐ

์‚ฌ์šฉ์ž ์ž…๋ ฅ์— ๋”ฐ๋ผ <, >, >=, <=, = ์™€ ๊ฐ™์€ ์—ฐ์‚ฐ์ž๊ฐ€ ๋‹ฌ๋ผ์ง€๋Š” ๊ฒฝ์šฐ์—๋Š” Dynamic SQL์„ ์‚ฌ์šฉํ•  ์ˆ˜๋ฐ–์— ์—†๋‹ค. ๊ทธ๋Ÿฌ๋‚˜. Static SQL๋กœ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด BETWENN ๊ตฌ๋ฌธ์„ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

SELECT * 
FROM TABLE 
WHERE COL BETWEEN :START_VAL AND :END_VAL;

 

์กฐ๊ฑด์— ๋”ฐ๋ผ :START_VAL๊ณผ :END_VAL์— ์ ์ ˆํ•œ ๊ฐ’์„ ๋ฐ”์ธ๋”ฉํ•˜์—ฌ ์—ฐ์‚ฐ์ž๋ฅผ ๋Œ€์ฒดํ•  ์ˆ˜ ์žˆ๋‹ค.

Reference