안녕하세요... mssql 을 열심히 공부중인 현업 ORACLE DBA
입니다.
얼마전 모 사이트에서 SQL 쪽 고수분과 토의 한 내용입니다. 너무
재미 있더군요... ^^;;
SQL TUNING을 제법 해본지라.... MSSQL 에도 옵티마이져
아키텍쳐와 비교하면서
테스트를 하고 있습니다. 데이터 베이스 성능에 가장 큰 이슈는
모니모니 해도 SQL TUNING 이슈겠죠.... ^^;;
테스트를 제법 많이 해보고 있는데요... 오라클과 MSSQL 의
옵티마이져에는 약간의 차이가 존재 하더군요...
1. 드라이빙 테이블의 선정....
오라클에서는 처리 범위가 적은 테이블을 드라이빙 테이블로
선정합니다. 물론 이는 상수값을 넘겨 받아서 각 테이블을 메치 하는
형태의 조인인 경우도 물론 그렇구요..
하지만 MSSQL 은 약간 다르더군요... 상수값을 받아서 메치 시키는
경우는 물론 처리 범위가 적은 테이블을 먼저 드라이빙으로 잡긴
하지만.. 단순 조인일 경우 여기서 말하는 건 NL 조인이 되겟쬬...
조건 없는 단순 조인의 경우는 보통 클러스터드 인덱스가 걸린
테이블을 우선하여 드라이빙 테이블로 선정하는 경향이 많았습니다.
또한 후행 테이블의 사이즈가 적은 경우를 더 선호 하더군요..
BOOK MARK 없이 LEAF LEVEL 에서의 SCAN 을 위한 IO 절감을 위해
드라이빙 테이블을 그렇게 선호하는 거 같습니다. 물론 조건에 따라
조금씩은 다르겠지만... 대부분이 그렇더군요...
select j.job_desc,e.fname from jobs j,employee e where j.job_id
= e.job_id
|--Nested Loops(Inner Join, OUTER
REFERENCES:([j].[job_id]))
|--Clustered Index
Scan(OBJECT:([pubs].[dbo].[jobs].[PK__jobs__117F9D94] AS
[j]))
|--Index Seek(OBJECT:([pubs].[dbo].[employee].[emp_idx] AS
[e]), SEEK:([e].[job_id]=[j].[job_id]) ORDERED FORWARD)
employee 에 job_id 에 넌 클러스터드 인덱스를 생성후 조인하니
클러스터드 인덱스가 있는 테이블이 먼저 드라이빙 테이블로 선정된
것을 볼수 있습니다. 이건 한 예구요.. 상황에 따라서 많겠죠...
제가 에디터를 잘 사용못해서 실행계획을 다 붙이질
못하겠군요.....
좀더 많은 내용들이 있는데... 예를 여러가 들기가 좀 힘드네요...
^^;;
뭐 상황에 따라서는 조인시 employee 를 먼저 드라이빙으로
잡을수도 있겠죠.. 즉 연결고리에 해당하는 job_id 를 깬다면 인덱스가
없는 테이블 부터 드라이빙으로 잡히겠죠..
어느 테이블을 드라이빙으로 잡느냐는 아주 중요합니다. 즉 그
쿼리의 성능을 좌우할 정도로 중요하죠... 하지만... 다양한 상황에
따라서 실행계획을 힌트나 기타 select list 등의 조작을 통해서 내가
유도 하는 바로 시행계획을 틀어 낼수 있씁니다.
서브 쿼리나 인라인뷰 및 힌트나 기타 튜닝 관련 팁을 알려
드리고자 했는데...
이 에디터를 제가 잘 사용하지 못해서... 여기서 그냥 둘까
하네요....
수십가지 정도 테스트 하면서 다양한 옵티마이져 핸들링에 대한
내용을 쓰려 했는데.. 공유되지 못해서 죄송하네요.... ^^;;
담에 시간 많이 나면 다시 시작하도록 하겠습니다.
수고하세요...
|