๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
ORACLE/Tunning

[Oracle] ์กฐ์ธ์˜ ์ข…๋ฅ˜ - Nested,Sorted,Hash

by ๐ŸŒปโ™š 2020. 10. 7.

Join

RDBMS์—์„œ๋Š” ์ •๊ทœํ™”์— ์˜ํ•ด ์—ฐ๊ด€๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์—ฌ๋Ÿฌ๊ฐœ์˜ ํ…Œ์ด๋ธ”๋กœ ๋‚˜๋ˆ„๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์›ํ•˜๋Š” ํ˜•์‹์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์˜ค๊ธฐ ์œ„ํ•ด ์—ฌ๋Ÿฌ๊ฐœ์˜ ํ…Œ์ด๋ธ”์„ ์—ฐ๊ฒฐํ•˜์—ฌ ์‚ฌ์šฉํ•˜๋Š”๋ฐ ์ด๋ฅผ Join์„ ํ†ตํ•ด์„œ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Join์ž‘์—…์„ ํ• ๋•Œ๋„ ์˜ตํ‹ฐ๋งˆ์ด์ €๋Š” ์–ด๋–ค ๋ฐฉ์‹์œผ๋กœ ์กฐ์ธ์„ ํ• ์ง€ ์‹คํ–‰๊ณ„ํš์„ ์„ธ์šฐ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์ด๋ฒˆ ๊ธ€์—์„œ๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋‚ด๋ถ€์ ์œผ๋กœ ์–ด๋–ป๊ฒŒ ์กฐ์ธ์„ ํ•˜๋Š”์ง€ ์•„๋ž˜ 3๊ฐ€์ง€ ๋ฐฉ์‹์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

  • Nested Loop Join
  • Sorted Merge Join
  • Hash Join

 

์‹ค์Šตํ™˜๊ฒฝ

OS : Red Hat Enterprise Linux Server release 6.10
DB : Oracle 11.2.0.1
SID : orcl
user : jamong

 

ํ…Œ์ด๋ธ” ๊ตฌ์กฐ

SYS@orcl> create table jamong.departments as select * from hr.departments;
SYS@orcl> create table jamong.employees as select * from hr.employees;
SYS@orcl> alter table jamong.departments add constraint pk_departments primary key(department_id);
SYS@orcl> alter table jamong.employees add constraint pk_employees primary key(employee_id);
JAMONG@orcl> create index employees_dept_idx on employees(department_id);

JAMONG@orcl> alter session set statistics_level=all;

HR ๊ณ„์ •์˜ ๊ธฐ๋ณธ ํ…Œ์ด๋ธ”์˜ ๋ฐ์ดํ„ฐ๋ฅผ  jamong ๊ณ„์ •์œผ๋กœ ์ด๋™ํ•˜์—ฌ ์‚ฌ์šฉํ–ˆ๊ณ , ์ปค์„œ์— ์กด์žฌํ•˜๋Š” ์‹คํ–‰๊ณ„ํš์„ ์ˆ˜์‹œ๋กœ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด statistics_level์„ all๋กœ ์„ค์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. test table์— department_id์— ๋Œ€ํ•œ ์ธ๋ฑ์Šค๋„ ์ƒ์„ฑํ•ด์ค๋‹ˆ๋‹ค.

 

xplan.sql

set linesize 150
set pagesize 100

select * from table(dbms_xplan.display_cursor(null,null,'allstats last cost'));

start.sql

conn jamong/jamong
alter session set max_dump_file_size=unlimited;
alter session set events '10046 trace name context forever, level 12';

end.sql

alter session set events '10046 trace name context off';

define _editor=vi

undefine trace
column trace_file new_value trace

SELECT value AS trace_file
FROM v$diag_info
WHERE name = 'Default Trace File';

!tkprof &trace output.trc sys=no
ed output.trc

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

 

[Oracle] ์‹คํ–‰๊ณ„ํš ํ™•์ธ ๋ฐฉ๋ฒ• XPLAN, AutoTrace, SQL Trace

์‹คํ–‰๊ณ„ํš ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋ฌธ์ œ ํ’€๋•Œ๋ฅผ ๋– ์˜ฌ๋ ค๋ด…์‹œ๋‹ค. ๋ฌธ์ œ๋ฅผ ์ฝ๊ณ  ์–ด๋–ค ๋ฐฉ์‹์œผ๋กœ ํ’€์–ด์•ผ ์ •ํ™•๋„์™€ ํšจ์œจ์„ฑ์„ ์žก์„ ์ˆ˜ ์žˆ์„์ง€ ๊ณ ๋ฏผํ•ฉ๋‹ˆ๋‹ค. ์™„์ „ํƒ์ƒ‰์„ ํ•ด์•ผํ•˜๋Š”์ง€, ์ด๋ถ„ํƒ์œผ๋กœ ์‹œ๊ฐ„๋ณต์žก๋„๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ

myjamong.tistory.com

 

 

1. Nested Loop Join

Nested Loop Join์˜ ๋ฐฉ์‹์€ ๋‘๊ฐœ์˜ ํ…Œ์ด๋ธ”์˜ ํ–‰์„ ๊ฐ๊ฐ ๋ชจ๋‘ ํ™•์ธํ•˜์—ฌ ์กฐ์ธํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ํ‘œํ˜„ํ•˜์ž๋ฉด ์ค‘์ฒฉ๋œ for๋ฌธ์ž…๋‹ˆ๋‹ค. inner์™€ outer loop์ด ์žˆ๋“ฏ์ด ์กฐ์ธ์—๋Š” dirving๊ณผ driven ํ…Œ์ด๋ธ”์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์‹คํ–‰๊ณ„ํš์—์„œ ๋จผ์ € ์‹คํ–‰๋˜๋Š” ํ…Œ์ด๋ธ”์ด driving ํ…Œ์ด๋ธ”์ด๊ณ  ๋‚˜์ค‘์— ์‹คํ–‰๋˜๋Š” ๊ฒƒ์ด driven ํ…Œ์ด๋ธ”์ž…๋‹ˆ๋‹ค. ์ค‘์ฒฉ๋œ for ๋ฌธ์ด๋ผ๊ณ  ํ‘œํ˜„ํ•œ ์ด์œ ๋Š” ๊ฐ๊ฐ ํ…Œ์ด๋ธ”์„ ๋ชจ๋‘ ์ฝ๊ณ  ํ™•์ธํ•˜๋Š” ๊ฒƒ์ด์•„๋‹ˆ๋ผ ๊ฐ ํ–‰๋ณ„๋กœ ํ™•์ธํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํ–‰์ด ์ ์€ ํ…Œ์ด๋ธ”์„ driving ํ…Œ์ด๋ธ”๋กœ ์„ ์ •ํ•˜๋Š” ๊ฒƒ์ด ๋น ๋ฅธ๊ฒฐ๊ณผ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ๋˜ํ•œ ์กฐ์ธ ์ปฌ๋Ÿผ์— ์ธ๋ฑ์Šค๊ฐ€ ์žˆ์–ด์•ผ ํ…Œ์ด๋ธ” ์ „์ฒด๋ฅผ ํƒ์ƒ‰ํ•˜์ง€ ์•Š๊ณ  ํ•„์š”ํ•œ ํ–‰์—๋Œ€ํ•ด์„œ๋งŒ ํƒ์ƒ‰ํ•˜์—ฌ ํšจ์œจ์ ์ž…๋‹ˆ๋‹ค.

 

์˜ˆ์‹œ

JAMONG@orcl> create table test as select * from employees;

JAMONG@orcl> insert into test select * from test;
JAMONG@orcl> insert into test select * from test;
JAMONG@orcl> insert into test select * from test;
JAMONG@orcl> insert into test select * from test;
JAMONG@orcl> insert into test select * from test;
JAMONG@orcl> insert into test select * from test;
JAMONG@orcl> insert into test select * from test;
JAMONG@orcl> insert into test select * from test;
JAMONG@orcl> insert into test select * from test;
JAMONG@orcl> insert into test select * from test;
JAMONG@orcl> insert into test select * from test;
JAMONG@orcl> insert into test select * from test;
JAMONG@orcl> insert into test select * from test;

JAMONG@orcl> create index test_dept_idx on test(department_id);

์„ฑ๋Šฅ์˜ ํ™•์—ฐํ•œ ์ฐจ์ด๋ฅผ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด testํ…Œ์ด๋ธ”์„ 90๋งŒ๊ฑด ์ •๋„์˜ ํ…Œ์ด๋ธ”๋กœ ์ƒ์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค. 27๊ฑด์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ–๊ณ  ์žˆ๋Š” departments ํ…Œ์ด๋ธ”๊ณผ ์กฐ์ธํ•ด์„œ ๊ฒฐ๊ณผ๋ฅผ ํ™•์ธํ•ด๋ณผ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

 

JAMONG@orcl> @start
JAMONG@orcl>
select /*+ leading(e) use_nl(d) */ count(*)
from test e, departments d 
where e.department_id = d.department_id;
JAMONG@orcl> @end

ํžŒํŠธ๋ฅผ ์‚ฌ์šฉํ•ด์„œ leading --> test ํ…Œ์ด๋ธ”์„ driving ํ…Œ์ด๋ธ”๋กœ ์„ค์ •ํ•˜๊ณ  ํŠน๋ณ„ํ•œ ํ•„ํ„ฐ๋ง์—†์ด Nested Loop Join์œผ๋กœ ์‹คํ–‰ํ•˜๊ณ  ์‹คํ–‰๊ณ„ํš์„ ๊ทธ๋ฆผ์œผ๋กœ ๊ทธ๋ ค๋ดค์„ ๋•Œ ์œ„์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์‹คํ–‰ํ•˜๋Š”๋ฐ 70์ดˆ์ •๋„๊ฐ€ ์†Œ์š”๋ฌ๊ณ  ๊ทธ๋Ÿผ diving๊ณผ driven ํ…Œ์ด๋ธ”์„ ๋ฐ”๊พธ๊ณ  ์‹คํ–‰ํ•œ ํ›„ ๋น„๊ตํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

JAMONG@orcl> @start
JAMONG@orcl>
select /*+ leading(d) use_nl(e) */ count(*)
from test e, departments d 
where e.department_id = d.department_id;
JAMONG@orcl> @end

๊ฒฐ๊ณผ์ ์œผ๋กœ ๋ดค์„๋•Œ driving ํ…Œ์ด๋ธ”์ด departments์ผ ๋•Œ ์‹คํ–‰ ์‹œ๊ฐ„ 27์ดˆ๋กœ 71์ดˆ๋ณด๋‹ค 2๋ฐฐ ์ด์ƒ ๋น ๋ฅธ ์†๋„๋กœ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ–๊ณ  ์™”์Šต๋‹ˆ๋‹ค. ์‹คํ–‰๊ณ„ํš์„ ๋ดค์„๋•Œ ์ฝ๋Š” ๋ธ”๋ก์˜ ๊ฐฏ์ˆ˜๋Š” ํฌ๊ฒŒ ์ฐจ์ด๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ๋Š” ๊ฐ™์œผ๋ฏ€๋กœ ๋ฐ˜ํ™˜๋˜๋Š” row์˜ ๊ฐฏ์ˆ˜๋„ ๊ฐ™์€๋ฐ ์†๋„์ฐจ์ด๋Š” ํฌ๊ฒŒ ๋‚ฉ๋‹ˆ๋‹ค. count๋œ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ›๋Š”๊ฒƒ์œผ๋กœ Table์— ๋Œ€ํ•œ Random Access ํ•„์š”์—†์ด ์ธ๋ฑ์Šค๋งŒ ๊ฐ–๊ณ  ๊ฒฐ๊ณผ๋ฅผ ๋ฐ›์•„์™”์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ์–ด๋–ค ์ด์œ ๋กœ ์ฐจ์ด๊ฐ€ ๋‚œ๊ฑธ๊นŒ์š”? ๋ฐ”๋กœ driving ํ…Œ์ด๋ธ”์˜ ํ–‰์˜ ๊ฐฏ์ˆ˜๊ฐ€ ๋น„๊ต์  ์ ๋‹ค๋Š” ์ด์œ ์ด๊ณ  Nested Loop Join์ด ๋ ˆ์ฝ”๋“œ ํ•˜๋‚˜์”ฉ ์ˆœ์ฐจ์ ์œผ๋กœ ์กฐ์ธ์ž‘์—…์„ ํ•œ๋‹ค๋Š” ํŠน์ง•์ด ํ™•์‹คํ•˜๊ฒŒ ๋ณด์—ฌ์ง‘๋‹ˆ๋‹ค.

 

driving ํ…Œ์ด๋ธ”์ด test์ผ๋•Œ์˜ ์ƒํ™ฉ์„ ๋จผ์ € ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๋ ˆ์ฝ”๋“œ ํ•˜๋‚˜์”ฉ ํ™•์ธํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋จผ์ € TEST_DEPT_IDX๋ฅผ ๊ฐ๊ฐ 90๋งŒ๋ฒˆ ํ™•์ธํ•˜๋ฉด์„œ PK_DEPARTMENTS ์ธ๋ฑ์Šค๋ฅผ Unique Scan์œผ๋กœ ํ•œ๋ฒˆ์”ฉ๋งŒ ํ™•์ธํ•˜์—ฌ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ›์•„์˜ต๋‹ˆ๋‹ค. ๊ทธ๋ฆผ์œผ๋กœ ํ‘œํ˜„ํ•˜์ž๋ฉด ์•„๋ž˜์™€๊ฐ™์ด ๋ป—์–ด๋‚˜๊ฐ€๋ฉด์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐ์ธํ•ฉ๋‹ˆ๋‹ค.

 

driving ํ…Œ์ด๋ธ”์ด departments์ผ๋•Œ๋Š” ๋ ˆ์ฝ”๋“œ๋ฅผ PK_DEPARTMENTS์—์„œ ๋จผ์ € ๋‹ค ํ™•์ธํ•˜๊ณ  ๊ฐ ๋ ˆ์ฝ”๋“œ๋ณ„๋กœ Range Scan์„ ํ†ตํ•ด TEST_DEPT_IDX๋ฅผ ํƒ์ƒ‰ํ•ฉ๋‹ˆ๋‹ค. ์•„๋ž˜์™€ ๊ฐ™์€ ์‹์œผ๋กœ ์ˆœํšŒํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋ฆผ์œผ๋กœ๋งŒ ๋ด๋„ ํ™•์—ฐํ•˜๊ฒŒ ์ฐจ์ด๋ฅผ ๋Š๋‚„์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. driving ํ…Œ์ด๋ธ”์˜ ๋ ˆ์ฝ”๋“œ๊ฐ€ ์ ์€ ๊ฒฝ์šฐ driven ํ…Œ์ด๋ธ”์—์„œ ์ผ์ผํžˆ Root ๋ธ”๋ก์„ ๊ฑฐ์น˜๋Š” ์ผ์ด ์ž‘๊ธฐ ๋•Œ๋ฌธ์— ํ›จ์”ฌ ๋น ๋ฅธ ์†๋„๋กœ ๊ฒฐ๊ณผ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฌผ๋ก , ์ธ๋ฑ์Šค๊ฐ€ ๋ชจ๋‘ ์—†๋Š” ํ…Œ์ด๋ธ”์˜ ๊ฒฝ์šฐ์—๋Š” ์–ด๋–ค ๊ฒฝ์šฐ์—๋“  ๋ชจ๋‘ Full Table Scan์„ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์˜๋ฏธ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿผ ์ด๋ฒˆ์—๋Š” count๊ฐ€ ์•„๋‹Œ ํ…Œ์ด๋ธ”์˜ ๊ฒฐ๊ณผ๋ฅผ ์ถœ๋ ฅํ•˜์—ฌ Random Accessํ–ˆ์„ ๋•Œ์˜ ๊ฒฝ์šฐ๋ฅผ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

e_lead.sql

select /*+ leading(e) use_nl(d) */
        e.employee_id,
        e.first_name,
        e.salary,
        d.department_id,
        d.location_id
from test e, departments d
where e.department_id = d.department_id
and e.employee_id > 150
and d.location_id = 2700;

d_lead.sql

select /*+ leading(d) use_nl(e) */
        e.employee_id,
        e.first_name,
        e.salary,
        d.department_id,
        d.location_id
from test e, departments d
where e.department_id = d.department_id
and e.employee_id > 150
and d.location_id = 2700;

๊ฒฐ๊ณผ ์ถœ๋ ฅ๋˜๋Š” ๋‚ด์šฉ์ด ๋งŽ์•„์„œ script์— ์ž‘์„ฑ ํ›„ termout ์˜ต์…˜์„ ๋„๊ณ  ์‹ค์Šต์ง„ํ–‰ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

 

JAMONG@orcl> set termout off
JAMONG@orcl> @start
JAMONG@orcl> @e_lead
JAMONG@orcl> set termout on
JAMONG@orcl> @end

test Table์ด Driving Table์ธ ๊ฒฝ์šฐ์ž…๋‹ˆ๋‹ค. ์šฐ์„  ์ถœ๋ ฅํ•˜๋Š” ๋ฐ์ดํ„ฐ์˜ ์–‘์ด ๋งŽ์•„ Test ํ…Œ์ด๋ธ”์„ Full Table Scan์„ ํ†ตํ•ด ํƒ์ƒ‰์„ํ•˜๋ฉด์„œ employee_id ๊ฐ€ 150 ์ดํ•˜์ธ ๋ ˆ์ฝ”๋“œ๋Š” ํ•„ํ„ฐ๋งํ•œ๊ฒƒ์œผ๋กœ ๋ด…๋‹ˆ๋‹ค. ์ฆ‰ 90๋งŒ๊ฑด์„ ์ „๋ถ€ํ™•์ธํ•˜๋ฉด์„œ ๋Œ€๋žต 45๋งŒ๊ฑด์˜ ๋ฐ์ดํ„ฐ๊ฐ€ ํ•„ํ„ฐ๋ง๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋‹ค์Œ 45๋งŒ๊ฑด์— ๋Œ€ํ•ด์„œ PK_DEPARTMENTS ์ธ๋ฑ์Šค์™€ ์กฐ์ธ์ž‘์—…์„ํ•ฉ๋‹ˆ๋‹ค. ์กฐ์ธ๋œ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ–๊ณ   departments ํ…Œ์ด๋ธ”๊ณผ ๋‹ค์‹œ ์กฐ์ธํ•˜๊ฒŒ ๋˜๋Š”๋ฐ ROWID์— ๋Œ€ํ•œ ์กฐ์ธ์œผ๋กœ Accessํ•˜๋ฉด์„œ location_id๊ฐ€ 2700์ธ ๋ฐ์ดํ„ฐ๋ฅผ ํ•„ํ„ฐ๋งํ•ฉ๋‹ˆ๋‹ค.

 

driving table์—์„œ 45๋งŒ๊ฑด์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐ์ธํ•˜๋Š”๋ฐ ๊ฒฐ๊ณผ๋กœ 8000๊ฑด์ •๋„์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์–ป๋Š” ๊ฒƒ์€ ์ฝ์€ ๋ฐ์ดํ„ฐ ์ค‘ ์ƒ๋‹นํ•œ ์–‘์„ ๋ฒ„๋ฆฌ๋Š” ๊ฒƒ์œผ๋กœ ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š” ๊ฒƒ์œผ๋กœ ํŒ๋‹จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

JAMONG@orcl> set termout off
JAMONG@orcl> @start
JAMONG@orcl> @d_lead
JAMONG@orcl> set termout on
JAMONG@orcl> @end

์ด๋ฒˆ์—๋Š” departments ํ…Œ์ด๋ธ”์ด driving ํ…Œ์ด๋ธ”์ž…๋‹ˆ๋‹ค. ๊ฐ€์žฅ ๋จผ์ € Departments Table์„ Full Table Scanํ•˜๋ฉด์„œ location_id๊ฐ€ 2700์ธ ๋ ˆ์ฝ”๋“œ๋ฅผ ํ•„ํ„ฐ๋งํ•ด์„œ 1๊ฑด์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์–ป์Šต๋‹ˆ๋‹ค. ๊ทธ๋‹ค์Œ TEST_DEPT_IDX ์ธ๋ฑ์Šค๋ฅผ ํƒ์ƒ‰ํ•˜๋Š”๋ฐ departments ํ…Œ์ด๋ธ”์—์„œ ํ•˜๋‚˜์˜ ๋ ˆ์ฝ”๋“œ์— ๋Œ€ํ•ด์„œ๋งŒ ํ™•์ธํ•˜๋ฉฐ ์กฐ์ธํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ๊ทธ ์ดํ›„ TEST ํ…Œ์ด๋ธ” Access๋ฅผ ํ•˜๋ฉด์„œ employee_id๊ฐ€ 150 ๋ณด๋‹ค ๋†’์€ ์กฐ๊ฑด์„ ํ•„ํ„ฐ๋งํ•˜๋Š”๋ฐ ๊ณต๊ต๋กญ๊ฒŒ๋„ ์ด์ „์— ํ•„ํ„ฐ๋ง๋œ ๊ฒฐ๊ณผ๊ฐ€ ๋ชจ๋‘ ํ•ด๋‹น ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜์—ฌ ๋ฒ„๋ฆฌ๋Š” ํ–‰ ์—†์ด ๋ชจ๋‘ ROWID์— ๋Œ€ํ•ด ์กฐ์ธ ์ž‘์—…์„ ํ•˜๊ฒŒ๋ฉ๋‹ˆ๋‹ค.

 

์‹คํ–‰ํ•˜๋Š”๋ฐ ์†Œ์š”๋œ ์‹œ๊ฐ„๋งŒ ๋น„๊ตํ•ด๋ณด๋ฉด 52์ดˆ์—์„œ 1์ดˆ๋กœ ์ค„์ผ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๋ช‡๊ฐ€์ง€ ์กฐ๊ฑด์„ ์ฒ˜๋ฆฌํ•˜์—ฌ ์กฐ์ธํ•˜๊ธฐ ์ด์ „์— driving ํ…Œ์ด๋ธ”์—์„œ ํ•„ํ„ฐ์ž‘์—…์„ ์ง„ํ–‰ํ•˜์—ฌ driving table์˜ ํ–‰์„ ์ค„์—ฌ์ฃผ๋ฉด ํ™•์‹คํ•œ ์„ฑ๋Šฅ์ฐจ์ด๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋งŒํฐ Nested Loop Join์—์„œ๋Š” driving, driven ํ…Œ์ด๋ธ”์„ ์–ด๋–ป๊ฒŒ ์ง€์ •ํ•˜๋Š”์ง€๊ฐ€ ์ค‘์š”ํ•˜๊ณ  ์ธ๋ฑ์Šค์— ์˜์กด์ ์ž…๋‹ˆ๋‹ค.

 

ํŠน์ง•

  • driving ํ…Œ์ด๋ธ” ๊ฒฐ์ • ํ›„ driven ํ…Œ์ด๋ธ”์— ๋ฐ˜๋ณต์ ์ธ ์ ‘๊ทผ
  • ํ•œ ๋ ˆ์ฝ”๋“œ์”ฉ ์ˆœ์ฐจ์ ์œผ๋กœ ์ ‘๊ทผ
  • ๋งŽ์€ ์–‘์˜ ๋ฐ์ดํ„ฐ ์กฐ์ธ ์‹œ Random Access ์ฆ๊ฐ€
  • Random Access ์œ„์ฃผ์˜ ์กฐ์ธ ๋ฐฉ์‹
  • ์†Œ๋Ÿ‰์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐ์ธ ์‹œ ์‚ฌ์šฉ
  • ๋ถ€๋ถ„ ๋ฒ”์œ„ ์ฒ˜๋ฆฌ์— ์ตœ์ ํ™”
  • ์ธ๋ฑ์Šค ๊ตฌ์„ฑ ์ „๋Ÿ‰์ด ์ค‘์š”

 

2. Sorted Merge Join

Sorted Merge Join์€ ๋‘๊ฐœ์˜ ํ…Œ์ด๋ธ”์„ ์กฐ์ธ ์นผ๋Ÿผ์œผ๋กœ ์ •๋ ฌํ•˜์—ฌ ์กฐ์ธํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ์ •๋ ฌ๋œ ํ…Œ์ด๋ธ”๋กœ ์กฐ์ธํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ธ๋ฑ์Šค๋ฅผ ํ™œ์šฉํ•˜๋Š” ํšจ๊ณผ์™€ ๋น„์Šทํ•ฉ๋‹ˆ๋‹ค. Sorted Merge Join์€ Nested Loop Join์˜ ์กฐ์ธ๊ณผ ์ˆ˜ํ–‰ ๊ณผ์ •์ด ๋‹ค๋ฅด์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‹จ, PGA ์˜์—ญ์„ ์ด์šฉํ•˜์—ฌ ์ •๋ ฌ์ž‘์—…์„ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ž˜์น˜ ํ™•๋“ํ•  ํ•„์š”๊ฐ€ ์—†์–ด Index๋ฅผ ํ†ตํ•ด Table Accessํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ๋น ๋ฆ…๋‹ˆ๋‹ค. ์ด๋Ÿฌ ํ•œ ํŠน์„ฑ์„ ๊ฐ–๊ณ  ์žˆ์–ด ์กฐ์ธ๋˜๋Š” ์นผ๋Ÿผ์— ์ธ๋ฑ์Šค๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ์— ์œ ๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

 

์ธ๋ฑ์Šค๊ฐ€ ์—†๋Š” ๋‘ํ…Œ์ด๋ธ”์— ๋Œ€ํ•ด์„œ Nested Loop Join์„ ํ•˜๋Š” ๊ฒฝ์šฐ driving table์˜ ๊ฐ๊ฐ ํ–‰์— ๋Œ€ํ•ด driven table์„ Full Scanํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ธ๋ฑ์Šค์— ๋งŽ์ด ์˜์กดํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด, Sorted Merge Join์€ ์ธ๋ฑ์Šค๊ฐ€ ์—†์–ด๋„ ์กฐ์ธ์นผ๋Ÿผ์„ ๊ธฐ์ค€์œผ๋กœ ์ •๋ ฌํ•œ ํ›„ inner table ์กฐํšŒ์‹œ outer table์˜ ๊ฐ’์— ๋Œ€ํ•ด์„œ๋งŒ ์กฐ์ธํ•˜๋ฉด ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ธ๋ฑ์Šค๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ์— ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ๊ณ  ์ด๋Ÿฌํ•œ ์ •๋ ฌ ์ž‘์—…์— ๋Œ€ํ•œ ๋ถ€ํ•˜๋ฅผ ๊ฐ์ˆ˜ํ•œ๋‹ค๋ฉด Nested Loop Join ๋ณด๋‹ค ์œ ๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

์˜ˆ์‹œ

Sorted Merge Join์€ Hash join์˜ ๋“ฑ์žฅ์œผ๋กœ ์‚ฌ์šฉ์ด ๋งŽ์ด ์ค„์–ด๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์—ฌ์ „ํžˆ Sorted Merge Join์„ ์‚ฌ์šฉํ•˜๋Š”๊ฒŒ ์œ ๋ฆฌํ•œ ๊ฒฝ์šฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. Outer ์ง‘ํ•ฉ์ด ์ •๋ ฌ๋˜์–ด ์žˆ๋Š” ๊ฒฝ์šฐ์™€ Non equi join์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ์ž…๋‹ˆ๋‹ค.

 

์ฒซ๋ฒˆ์งธ๋Š” Outer ์ง‘ํ•ฉ์ด ์ •๋ ฌ๋˜์–ด ์žˆ๋Š” ๊ฒฝ์šฐ๋ฅผ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

JAMONG@orcl>
select 
    e.employee_id,
    e.first_name,
    e.salary,
    d.department_id,
    d.location_id
 from employees e, departments d 
 where e.department_id = d.department_id;
 JAMONG@orcl> @xplan

๋งŒ์•ฝ Outer Table์„ index๋ฅผ ์ด์šฉํ•œ ํƒ์ƒ‰์„ ํ•œ๋‹ค๋ฉด Sort Merge Join ์‹œ ์ •๋ ฌ ์ž‘์—…์„ ๋Œ€์ฒดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์œ„์˜ ์ฟผ๋ฆฌ์—์„œ๋„ Outer Table departments๋ฅผ Index Full Scan์— ์˜ํ•ด์„œ Table Access๋ฅผ ํ•œ ํ›„ employees ํ…Œ์ด๋ธ”์„ ์ฝ์–ด sorting ์ž‘์—…์„ ํ•ฉ๋‹ˆ๋‹ค. ์ดํ›„ merge ์ž‘์—…์„ ํ•˜๊ณ  ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ด์™€ ๊ฐ™์ด outer table์— ์ธ๋ฑ์Šค๋กœ ์ •๋ ฌ์ž‘์—…์„ ๋Œ€์ฒดํ•ด์„œ Sorted Merge Join์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

์ธ๋ฑ์Šค๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ์ด๋ฏธ Outer Table์ด ์ •๋ ฌ๋˜์–ด ์žˆ๋Š” ๊ฒฝ์šฐ ์กฐ์ธ์„ ์œ„ํ•ด ๋‹ค์‹œ  ์ •๋ ฌ์ž‘์—…์„ ํ•˜์ง€ ์•Š์•„๋„ ๋˜๋ฏ€๋กœ Sorted Merge Join์ด ์œ ๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

JAMONG@orcl>
select 
    d.department_name,
    e.sal_avg 
from 
    departments d,
    (
        select
            department_id,
            avg(salary) as sal_avg 
        from employees 
        group by department_id 
        order by department_id
    ) e 
where e.department_id = d.department_id;
JAMONG@orcl> @xplan

๊ฐ ๋ถ€์„œ๋ฅผ ๋ถ€์„œ์˜ ํ‰๊ท  ๊ธ‰์—ฌ์™€ ํ•จ๊ป˜ ์ถœ๋ ฅํ•˜๋Š” ์ฟผ๋ฆฌ์ž…๋‹ˆ๋‹ค. e ์ง‘ํ•ฉ์— ๋Œ€ํ•ด์„œ groupingํ•˜๊ณ  ์กฐ์ธ๋˜๋Š” ์นผ๋Ÿผ์œผ๋กœ ๋ฏธ๋ฆฌ ์ •๋ ฌ๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์˜ตํ‹ฐ๋งˆ์ด์ €๋Š” Sorted Merge Join์œผ๋กœ ์‹คํ–‰๊ณ„ํš์€ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

 

 

JAMONG@orcl> create table salgrade(grade number,losal number,hisal number);
JAMONG@orcl> insert into salgrade values(1,0,4000);
JAMONG@orcl> insert into salgrade values(2,4001,8000);
JAMONG@orcl> insert into salgrade values(3,8001,12000);
JAMONG@orcl> insert into salgrade values(4,12001,16000);
JAMONG@orcl> insert into salgrade values(5,16001,50000);

JAMONG@orcl> 
select 
    e.employee_id,
    e.salary,
    s.grade 
from employees e, salgrade s 
where e.salary between s.losal and s.hisal;
JAMONG@orcl> @xplan

๊ธ‰์—ฌ๋ณ„ ๋“ฑ๊ธ‰์„ ๋‚˜๋ˆ„๋Š” ํ…Œ์ด๋ธ” salgrade๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์ง์›์˜ ๋“ฑ๊ธ‰์„ ๊ฐ™์ด ์ถœ๋ ฅํ•˜๋Š” non equi join ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•ด๋ดค์Šต๋‹ˆ๋‹ค. ์–‘ ํ…Œ์ด๋ธ”์„ ์ •๋ ฌํ•˜๊ณ  sort merge join์„ ์˜ตํ‹ฐ๋งˆ์ด์ €๊ฐ€ ํƒํ•œ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์กฐ์ธ ์กฐ๊ฑด์— ๋งž๋Š” ๋ฒ”์œ„์— ๋Œ€ํ•ด ํ•„ํ„ฐํ•œ Inner table์„ ๊ฐ๊ฐ ์ก๋ ฌ๋œ ์ƒํƒœ๋กœ Outer Table๋กœ๋ถ€ํ„ฐ ์ˆœ์ฐจ์ ์œผ๋กœ ์ฝ์–ด non equi join์„ ํ•˜๋Š”๋ฐ ์œ ๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

ํŠน์ง•

  • ์กฐ์ธ ์นผ๋Ÿผ์œผ๋กœ ์ €๋ ฌ ํ›„ ์กฐ์ธ ์ˆ˜ํ–‰
  • ์‹ค์‹œ์ž‘์œผ๋กœ ์ธ๋ฑ์Šค๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ๊ณผ ๋น„์Šท
  • ์ •๋ ฌํ•  ๋ฐ์ดํ„ฐ๊ฐ€ ๋งŽ์€ ๊ฒฝ์šฐ ๋ถ€๋‹ด์ด ๊ฐ€์žฅ ํฐ ์กฐ์ธ ๋ฐฉ๋ฒ•
  • ๋‘ ํ…Œ์ด๋ธ” ๊ฐœ๋ณ„์ ์œผ๋กœ ์ฝ๊ณ  ์กฐ์ธ
  • Outer Table์— ์ธ๋ฑ์Šค๊ฐ€ ์žˆ์„ ๊ฒฝ์šฐ ์‚ฌ์šฉ
  • Outer Table์ด ์ •๋ ฌ๋˜์–ด ์žˆ์„ ๋•Œ ์‚ฌ์šฉ
  • Non equi join ์‚ฌ์šฉ ์‹œ ์‚ฌ์šฉ

 

3. Hash Join

Hash Join์€ Hash Table์„ ์ƒ์„ฑํ•˜์—ฌ Hash Function์— ์˜ํ•œ ํƒ์ƒ‰์„ ํ•˜์—ฌ ์กฐ์ธํ•ฉ๋‹ˆ๋‹ค. ์ฃผ๋กœ ๋Œ€์šฉ๋Ÿ‰์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์‚ฌ์šฉ๋˜๋ฉฐ ์ผ๋ฐ˜์ ์œผ๋กœ Nested Loop Join์ด๋‚˜ Sorted Merge Join๋ณด๋‹ค ๋น ๋ฅด๋‹ค๊ณ ํ•ฉ๋‹ˆ๋‹ค. ์•Œ๊ณ ๋ฆฌ์ฆ˜์—์„œ ์‹œ๊ฐ„ ๋ณต์žก๋„์˜ ๊ฐœ๋…์œผ๋กœ ๋ดค์„ ๋•Œ๋„ Hash Function์„ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด O(1)์˜ ์‹œ๊ฐ„ ๋ณต์žก๋„๋ฅผ ๊ฐ–๊ฒŒ๋˜๋‹ˆ๊นŒ ๋น ๋ฅผ์ˆ˜ ๋ฐ–์— ์—†๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ, ํ•ด์‹œ ์ถฉ๋Œ์„ ๋ฐฉ์ง€๋‚˜ ํ•ด์‹œ ์ฒด์ธ์˜ ํฌ๊ธฐ๊ฐ€ ์ปค์ง€๋Š” ๊ฒƒ์„ ๋ง‰๊ธฐ ์œ„ํ•ด ์ค‘๋ณต๋˜๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ์ ์€ ๊ฒฝ์šฐ์— ์‚ฌ์šฉ๋˜์–ดํ•˜๊ณ  Hash Table์„ ์ƒ์„ฑํ•˜๋Š”๋ฐ Hash Area์— ์ถฉ๋ถ„ํžˆ ๋‹ด๊ธธ ์ •๋„๋กœ ๋ฐ์ดํ„ฐ ์–‘์ด ์ž‘์•„์•ผํ•ฉ๋‹ˆ๋‹ค.

 

์˜ˆ์‹œ

JAMONG@orcl> 
select /*+use_hash(d,e)*/ 
    d.department_id,
    d.department_name,
    e.last_name,
    e.salary 
from departments d, employees e 
where d.department_id = e.department_id;
JAMONG@orcl> @xplan

ํžŒํŠธ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๊ฒฐ๊ณผ๋ฅผ ํ™•์ธํ•ด๋ดค์Šต๋‹ˆ๋‹ค. Hash Join ์ˆ˜ํ–‰์‹œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Hash Table์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Hash Join์ด ๋น ๋ฅด๋‹ค๊ณ  ํ•˜๋Š” ์ด์œ  ๋˜ํ•œ PGA์˜์—ญ์„ ์‚ฌ์šฉํ•˜์—ฌ Latch๋ฅผ ํ™•๋“ ๊ณผ์ •์ด ์—†์–ด ๋น ๋ฅด๊ฒŒ ๊ฒฐ๊ณผ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

ํŠน์ง•

  • ๋‘ ์ง‘ํ•ฉ ์ค‘ ํฌ๊ธฐ๊ฐ€ ์ž‘์€ ์ง‘ํ•ฉ์„ Outer Table๋กœ ๊ฒฐ์ •
  • Outer Table์ด Hash Area์— ๋‹ด๊ธธ ์ •๋„๋กœ ์ถฉ๋ถ„ํžˆ ์ž‘์„ ๋•Œ ์‚ฌ์šฉ
  • Outer Table์˜ ํ•ด์‹œ ํ‚ค ์นผ๋Ÿผ์— ์ค‘๋ณต๊ฐ’์ด ๊ฑฐ์˜ ์—†์„ ๋•Œ ์‚ฌ์šฉ
  • ๋Œ€๋Ÿ‰์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐ์ธ์‹œ ์‚ฌ์šฉ
  • ์†Œ๋Ÿ‰์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐ์ธํ•  ๋•Œ ์˜คํžˆ๋ ค ๋ถˆํ•„์š”ํ•œ I/O๊ฐ€ ์ฆ๊ฐ€ํ•  ์ˆ˜ ์žˆ์Œ
  • Equi Join์—์„œ๋งŒ ๊ฐ€๋Šฅ
  • ์กฐ์ธ ์นผ๋Ÿผ์— ์ ๋‹นํ•œ ์ธ๋ฑ์Šค๊ฐ€ ์—†๋Š”๋ฐ Nested Loop Join์ด ๋น„ํšจ์œจ ์ ์ผ ๋•Œ ์‚ฌ์šฉ
  • Nested Loop Join์—์„œ ์กฐ์ธ ์นผ๋Ÿผ์— ์ธ๋ฑ์Šค๊ฐ€ ์žˆ๋”๋ผ๋„ Random Access ๋ถ€ํ•˜๊ฐ€ ์‹ฌํ•  ๋•Œ ์‚ฌ์šฉ
  • Sort Merge Join ์‚ฌ์šฉ ์‹œ ๋‘๊ฐœ์˜ ์ง‘ํ•ฉ์ด ๋„ˆ๋ฌด ์ปท ์ •๋ ฌํ•˜๋Š”๋ฐ ๋ถ€ํ•˜๊ฐ€ ์‹ฌํ•  ๋•Œ ์‚ฌ์šฉ

 

๋Œ“๊ธ€