개요
조인 순서는 SQL 성능에 영향을 줄 수 있는 요소입니다.
주어진 내용은 조인 순서를 제어하기 위한 힌트(ordered , leading) 사용 방법과, 힌트를 사용하지 않고 조인 조건문을 통해 제어할 수 있는 방법에 대해 안내합니다.
참고
테스트는 아래와 같은 환경에서 진행하였습니다.
[tibero@T1:/]$ tbboot -v
Tibero 6 (DB 6.0 FS06_CS_1703)
Linux stopbugs 2.6.9-89.ELsmp #1 SMP Mon Jun 22 12:31:33 EDT 2009 x86_64 x86_64 x86_64 GNU/Linux version (little-endian)
Patch files (none)
방법
예제 수행을 위한 테이블 생성
t1, t2, t3, t4, t5 5 개 테이블을 생성합니다.
create table t1(c1, c2) as
select
level, level
from dual
connect by level <= 5000;
create table t2(c1, c2) as
select
level, level
from dual
connect by level <= 4000;
create table t3(c1, c2) as
select
level, level
from dual
connect by level <= 3000;
create table t4(c1, c2) as
select
level, level
from dual
connect by level <= 2000;
create table t5(c1, c2) as
select
level, level
from dual
connect by level <= 1000;
exec dbms_stats.gather_table_stats('TIBERO', 'T1');
exec dbms_stats.gather_table_stats('TIBERO', 'T2');
exec dbms_stats.gather_table_stats('TIBERO', 'T3');
exec dbms_stats.gather_table_stats('TIBERO', 'T4');
exec dbms_stats.gather_table_stats('TIBERO', 'T5');
SQL
복사
ORDERED 힌트를 이용한 조인순서 제어
조인 순서를 T1 -> T2 -> T3 -> T4 -> T5 로 만들고 싶다면 아래와 같이 ORDERED 힌트를 사용하고, from 절 뒤에 테이블을 순서대로 명시합니다.
set feedback off;
set
select /*+ ordered */ *
from t1, t2, t3, t4, t5
where
t1.c1 = t2.c1
and t1.c1 = t3.c1
and t1.c1 = t4.c1
and t1.c1 = t5.c1
and t1.c2 between 1 and 10;
set linesize 200
set pagesize 0
select * from table(dbms_xplan.display_cursor(null, null, 'BASIC LAST SQL -CARDS -COST -ELAPTIME'));
-----------------------------------------
| ID | Operation | Name |
-----------------------------------------
| 1 | HASH JOIN | |
| 2 | HASH JOIN | |
| 3 | HASH JOIN | |
| 4 | HASH JOIN | |
| 5 | TABLE ACCESS (FULL) | T1 |
| 6 | TABLE ACCESS (FULL) | T2 |
| 7 | TABLE ACCESS (FULL) | T3 |
| 8 | TABLE ACCESS (FULL) | T4 |
| 9 | TABLE ACCESS (FULL) | T5 |
-----------------------------------------
SQL
복사
LEADING 힌트를 이용한 조인순서 제어
조인 순서를 T1 -> T2 -> T4 -> T3 -> T5 로 만들고 싶다면 아래와 같이LEADING(t1 t2 t4 t3 t5) 힌트를 사용합니다.
select /*+ LEADING(t1 t2 t4 t3 t5) */ *
from t2, t5, t1, t3, t4
where
t1.c1 = t2.c1
and t1.c1 = t3.c1
and t1.c1 = t4.c1
and t1.c1 = t5.c1
and t1.c2 between 1 and 10;
set linesize 200;
set pagesize 0;
select * from table(dbms_xplan.display_cursor(null, null, 'BASIC LAST SQL -CARDS -COST -ELAPTIME'));
-----------------------------------------
| ID | Operation | Name |
-----------------------------------------
| 1 | HASH JOIN | |
| 2 | HASH JOIN | |
| 3 | HASH JOIN | |
| 4 | HASH JOIN | |
| 5 | TABLE ACCESS (FULL) | T1 |
| 6 | TABLE ACCESS (FULL) | T2 |
| 7 | TABLE ACCESS (FULL) | T4 |
| 8 | TABLE ACCESS (FULL) | T3 |
| 9 | TABLE ACCESS (FULL) | T5 |
-----------------------------------------
SQL
복사
힌트 사용 없이 조인순서 제어
조인 순서를 T1 -> T2 -> T4 -> T3 -> T5 로 만들고 싶다면 아래와 같이 where 절의 구문을 작성합니다.
t2.c1 값을 알아야 t4.c1과의 조인이 이루어지도록, 기존의 t1.c1 = t4.c1 조인 조건을 t1.c1 + 0*t2.c1 = t4.c1 형태로 변경하고, 이와 같이 다른 조인 조건도 변경합니다.
select *
from t2, t5, t1, t3, t4
where
t1.c1 = t2.c1
and t1.c1 + 0 * t2.c1 = t4.c1
and t1.c1 + 0 * t4.c1 = t3.c1
and t1.c1 + 0 * t3.c1 = t5.c1
and t1.c2 between 1 and 10;
set linesize 200;
set pagesize 0;
select * from table(dbms_xplan.display_cursor(null, null, 'BASIC LAST SQL -CARDS -COST -ELAPTIME'));
-----------------------------------------
| ID | Operation | Name |
-----------------------------------------
| 1 | HASH JOIN | |
| 2 | HASH JOIN | |
| 3 | HASH JOIN | |
| 4 | HASH JOIN | |
| 5 | TABLE ACCESS (FULL) | T1 |
| 6 | TABLE ACCESS (FULL) | T2 |
| 7 | TABLE ACCESS (FULL) | T4 |
| 8 | TABLE ACCESS (FULL) | T3 |
| 9 | TABLE ACCESS (FULL) | T5 |
-----------------------------------------
SQL
복사