조인은 1:1로 이루어 진다. | |
---|---|
1) TABLE1의 처리 범위인 10,000 로우의 첫번째 로우를 읽는다. 2) 읽혀진 TABLE1의 값에 대응하는 TABLE2의 로우를 찾는다 3) TABLE2의 조인 컬럼값과 대응되는 TABLE3의 로우를 찾는다. 4) TABLE1의 처리범위가 모두 끝날 때까지 계속한다. => 최소 10,000회 이상ACCESS |
1) TABLE3의 처리 범위인 2개 로우의 첫번째 로우를 읽는다. 2) 읽혀진 TABLE3의 값에 대응하는 TABLE2의 로우를 찾는다 3) TABLE2의 조인 컬럼값과 대응되는 TABLE1의 로우를 찾는다. 4) TABLE3의 두번째 로우를 읽어 위의 작업을 반복한다. => 최대 4회 이하ACCESS |
<대용량데이터베이스 솔루션1 84page 그림참고>
조인은 M:1로 이루어 진다. | |
---|---|
1) TABLE1의 처리 범위인 100 로우의 첫번째 로우를 읽는다. 2) 읽혀진 TABLE1의 값에 대응하는 TABLE2의 로우를 찾는다 => TABLE1과 TABLE2는 1:10의 비율로 되어 있으며 100%연결에 성공했다고 가정 3) TABLE1과 TABLE2의 연결작업에 성공한 각각의 로우들에 대응하는 TABLE3의 로우를 찾는다. 4) TABLE1의 두번째 로우를 읽어 위의 작업을 반복한다. => 2)번 연결작업에서 성공한 로우수 1000건, 3)번 연결 작업이 1000회 총 2000회의 연결작업 수행 |
1) TABLE1의 처리 범위인 100 로우의 첫번째 로우를 읽는다. 2) 읽혀진 TABLE1의 값에 대응하는 TABLE3의 로우를 찾는다. => 2개의 로우만 성공 했다고 가정 3) 위의 작업에서 성공한 로우들에 대응하는 TABLE2의 로우를 찾는다. 4) TABLE1의 두번째 로우를 읽어 위의 작업을 반복한다. => TABLE1과 TABLE3의 연결작업 100회, 연결에 성공한 결과와 TABLE2간의 연결작업 2회 총 102회의 연결작업 수행 |
<대용량데이터베이스 솔루션1 86page 그림참고>
1번의 경우 1) TAB1의 처리 범위인 첫번째 로우를 읽는다. 2) TAB2의 연결고리가 되는 인덱스가 있으므로 TAB1의 연결고리의 값에 대응되는 로우를 KEY2에서 찾는다. 3) KEY2에 있는 ROWID를 이용하여 TAB2를 읽는다. 4) TAB1의 두번째 로우를 읽어 위의 작업을 반복한다. |
2번의 경우 1) TAB2의 처리 범위인 첫번째 로우를 읽는다. 2) TAB1의 연결고리가 되는 인덱스가 있으므로 TAB2의 연결고리의 값에 대응되는 로우를 KEY1에서 찾는다. 3) KEY1에 있는 ROWID를 이용하여 TAB1를 읽는다. 4) TAB2의 두번째 로우를 읽어 위의 작업을 반복한다. |
![]() |
연결고리가 정상인 상태에서는 먼저 처리범위를 줄여 주는 테이블이 먼저 처리되면 수행속도가 향상된다.SELECT a.FLD1, ........., b.FLD1, ......... FROM TAB2 b, TAB1 a WHERE a.KEY1 = b.KEY2 AND b.FLD2 LIKE 'ABC%' AND a.FLD1 = '10'
<대용량데이터베이스 솔루션1 92,93page 그림참고>
사용자가 어느 방향이 먼저 처리되는 것이 유리한지를 알고 있다면 힌트나 사용제한 기능을 이용하여 튜닝을 하라
|
1) TAB1에서 처리해야 할 범위의 첫번째 로우를 읽는다. 2) TAB2의 KEY2에는 인덱스가 없으므로 TAB2를 전부 스캔하여 'KEY2=KEY1'을 만족하는 로우를 찾는다. 3) 값을 찾더라도 멈추지 않고 테이블 끝까지 스캔한다. 4) TAB1의 두번째 로우를 읽어 TAB2의 전체 테이블 스캔을 한다.(TAB1의 처리범위가 끝날 때까지) |
1) '연결고리 정상'상태의 두번째 그림과 동일함.(TAB2는 좌측과 달리 한번만 액세스 된다.) ※ 연결고리가 어느 한쪽에 이상이 있는 경우는 이상이 발생한 테이블을 반드시 먼저 처리해야한다. 옵티마이져는 연결고리의 어느 한쪽에 인덱스가 없으면 무조건 없는 쪽을 먼처 처리하도록 실행계획을 수립한다. |
<대용량데이터베이스 솔루션1 95,96page 그림참고>
![]() |
연결고리 이상상태를 발생시키는 유형
|
![]() |
튜닝의 절차
|
1) TAB1에서 처리해야 할 전체범위를 하나씩 스캔하여 대응되는 TAB2의 로우를 연결한다. 2) TAB1에서 처리해야 할 로우의 범위가 1,000건이라면 1,000번의 연결작업이 랜덤 액세스방식으로 수행한다. 3) 연결된 로우들은 수행시킨 SQL에 따라 추가적인 2차 가공을 한 후 운반단위만큼 추출한다. 4) 1,000번의 연결을 위해 단 한번의 SQL이 수행한다. |
1) TAB1의 로우수에 대응하는 TAB2의 로우들을 랜덤으로 액세스한다. 2) 각각의 연결작업마다 별도의 SQL이 수행되어 연결작업에만 1,000번의 SQL이 수행된다. 3) 1,001의 SQL이 수행된다. |
<대용량데이터베이스 솔루션1 104page 그림참고>
SELECT a.FLD1, ........., b.FLD1, ......... FROM TAB2 b, TAB1 a WHERE a.KEY1 = b.KEY2 AND a.FLD1 = '10' ORDER BY a.FLD2 |
1) SELECT FLD1, ........., FLDn FROM TAB1 WHERE FLD1 = '10' ORDER BY FLD2 |
2) SELECT COL1, ........., COLn FROM TAB2 WHERE KEY2 = :a.KEY1 |
<대용량데이터베이스 솔루션1 106page 그림참고>
SELECT b.부서명, SUM(a.매출액) FROM TAB1 a, TAB2 b WHERE a.부서코드 = b.부서코드 AND a.매출일 LIKE '9503%' GROUP BY b.부서명 |
1) SELECT 부서코드, sum(a.매출액) FROM TAB1 WHERE 매출일 LIKE '9503%' GROUP BY 부서코드 |
2) SELECT 부서명 FROM TAB2 WHERE 부서코드 = :a.부서코드 |
<대용량데이터베이스 솔루션1 108page 그림참고>
1) 단 한번의 SQL이 수행. 2) SQL내에서 조인된 테이블의 모든 컬럼을 마음대로 가공가능 |
1)'운반단위 + 1'번의 SQL이 수행. 2) 별도의 언어를 통하여 추가적인 가공 |
<대용량데이터베이스 솔루션1 108page 그림참고>
![]() |
|
![]() |
쿼리에서의 활용
|
SELECT a.FLD1, ........., b.COL1, ......... FROM TAB1 a, TAB2 b WHERE a.KEY1 = b.KEY2 AND a.FLD1 = 'AB' AND b.FLD2 = '10'
1) TAB1의 FLD1인덱스를 경유하여 FLD1 = 'AB'인 처리범위 중 첫번째 로우 액세스한다. 2) FLD1인 인덱스에 있는 ROWID에 의해 TAB1로우를 액세스한다. 3) TAB2의 KEY2인덱스를 이용하여 대응되는 인덱스 로우를 찾는다. 4) KEY2인덱스에 있는 ROWID에 의해 TAB2의 로우를 액세스 한다. 5) FLD2 = '10'의 값을 비교(check)하여 조건을 만족하면 최종적인 결과를 운반단위로 보낸다. 6) FLD1 인덱스의 두번째 로우를 읽어 위의 작업을 반복하여 만약 부분범위처리가 가능하다면 운반단위가 채워질 때까지만 수행되고 전체범위처리라면 FLD1범위가 끝날 때까지 계속(Nested)해서 반복(Loop) 수행한다. |
<대용량데이터베이스 솔루션1 111page 그림참고>
![]() |
특징 1) 순차적으로 처리된다. 선행테이블(Driving table)의 처리범위에 있는 각각의 로우들이 순차적으로 수행될 뿐만 아니라 테이블 간의 연결도 순차적이다. (순차적) |
![]() |
1) 부분범위처리를 하는 경우에 주로 유리해진다. |
SELECT a.FLD1, ........., b.COL1, ......... FROM TAB1 a, TAB2 b WHERE a.KEY1 = b.KEY2 AND a.FLD1 = 'AB' AND b.FLD2 = '10'
1) TAB1의 FLD1인덱스를 경유하여 FLD1 ='AB'인 범위를 차례로 액세스 하여 연결고리인 KEY1의 값으로 정렬해 둔다. 2) TAB2도 FLD2인덱스를 경유하여 FLD2 = '10'인 범위를 차례로 액세스하여 연결고리인 KEY2의 값으로 정렬해 둔다. 3) 두개의 정렬된 결과를 스캔하면서 KEY1 = KEY2를 만족하는 로우를 찾도록 머지하여 운반단위가 채워지면 추출한다. |
<대용량데이터베이스 솔루션1 113page 그림참고>
![]() |
특징 1) 동시에 처리된다. 테이블 각자가 자신의 처리범위를 액세스하여 정렬해 둔다.(동시적) |
![]() |
사용기준 1) 전체범위처리를 하는 경우에 주로 유리해진다. |
SELECT a.FLD1, ........., b.COL1, ......... FROM TAB1 a, TAB2 b WHERE a.KEY1 = b.KEY2 AND a.FLD1 = 'AB'
b.FLD2 = '10' 조건을 없앰 | |
---|---|
1) TAB1의 FLD1 인덱스를 경유하여 FLD = 'AB'인 처리범위 중 첫번째 로우를 액세스한다. 2) FLD1 인덱스에 있는 ROWID에 의해 TAB1의 로우를 액세스한다. 3) TAB2의 KEY2 인덱스를 이용하여 대응 되는 인덱스 로우를 찾는다. 4) KEY2 인덱스에 있는 ROWID에 의해 TAB2의 로우를 액세스한다. 액세스된 로우의 모든 컬럼값들은 상수값이 되며 추가적인 조건이 없으므로 그대로 운반단위로 옮겨진다. 5) FLD1 인덱스의 두번째 로우를 읽어 위의 작업을 반복한다. 부분범위처리라면 오히려 체크 기능이 없어짐으로써 더 빨리 운반단위를 채울수 있다. |
1) TAB1은 FLD1 인덱스를 경유하여 FLD1 = 'AB'인 범위를 차례로 액세스하여 연결고리 인 KEY1의 값으로 정렬해 둔다. 2) TAB2는 전체 테이블을 차례로 액세스하여 연결고리인 KEY2의 값으로 정렬해 둔다. 3) 두개의 정렬된 결과를 스캔하면서 KEY1 = KEY2를 만족하는 로우를 찾도록 머지하여 운반단위가 채워지면 추출한다. 액세스 범위가 훨씬 증가했고 머지할 양 또한 많이 늘어나 일량이 훨씬 증가 되었다 |
<대용량데이터베이스 솔루션1 116,117page 그림참고>
SELECT a.FLD1, ........., b.COL1, ......... FROM TAB1 a, TAB2 b WHERE a.KEY1 = b.KEY2 ORDER BY a.FLD5, b.COL5
양쪽 조건을 모두 없앰 ORDER BY를 하여 전체 범위처리 | |
---|---|
Nested Loop | Sort Merge |
어느 한쪽이 먼저 전체 테이블 스캔을 하면서 읽혀진 KEY1의 상수값에 대응되는 KEY2 인덱스를 경유하여 TAB2를 찾게된다. TAB2 전체 테이블을 대상으로 랜덤 액세스가 발생한다. 만일 ORDER BY를 사용하지 않았다면 부분범위처리를 하게 되므로 아주 빠른 수행속도를 보장한다. |
각각의 테이블에 대해 전체 테이블을 스캔하여 연결고리가 되는 컬럼으로 정렬하여 머지한다. 랜덤으로 전체 테이블을 액세스하는 것보다 스캔방식으로 전체 테이블을 액세스하는 것이 유리하다. |