SQL Linked Server Best Practice

1.
remote server 에 SP 를 만들고 그걸 호출한다. 이게 젤 좋다.

2.
remote 서버에 SP를 만들 권한이 없다면 OPENQUERY 를 사용한다. 이렇게 하면 Linked Server 쪽을 호출할때 메타데이터의 교환이 최소화되어서 매우 빠른 속도로 쿼리가 수행된다.

insert into OPENQUERY(REMOTE, 'select col1, col2 from test.dbo.test_table where 1=0')
values ('aaaa','bbb')

update OPENQUERY(REMOTE, 'select col1, col2 from test.dbo.test_table where col3=1')
set col1 = 'aaaa', col2 = 'bbb'

참고1) OPENQUERY 의 두번째 인자인 SQL은 변수를 받을 수 없다. 만약 변수를 넘겨야 한다면 update 문을 통째로 동적SQL로 만들고 그걸 sp_executesql 로 호출한다. MSDN 에 이 내용을 담은 KB문서가 있는데 못찼겠다.

참고2) update 의 대상이 OPENQUERY 로 읽어오는 remote table 일 경우 update OPENQUERY().. set ... from localtable1 join OPENQUERY() 같은 형태의 SQL은 실행되지 않을 것이다. (긴가민가하다-_-) OLEDB가 뭔가 에러를 냈던 것으로 기억.

참고3) OPENQUERY 와 관련된 문서들

SQL Server 에서 Oracle Table Query 하기

SQL Server 에서 Oracle 에 DDL 수행하기

3.
left join 에는 remote table 을 사용하지 않는다. 예를 들어

select *
from dbo.localtable l
left join remotesvr.test.dbo.test_table r on l.col1 = b.col2

와 같이 left join 에 remote table 을 쓰면 remote table scan 을 해서 몽땅 다 읽어온 다음에 outer join 을 수행할 가능성이 높다. 따라서 실행계획을 반드시 확인해봐야 한다. SQL서버 옵티마이저가 이럴때 보면 좀 멍청한 것 같다. inner loop join 은 괜찮다. 그런데 remote table 과 loop join 을 한다는 것 자체가 network io 를 발생시키는 일이기 때문에 당연히 local table 과 join 하는 것 보다 엄청나게 느릴 수 밖에 없다.

결국 결론은, DB분산을 해도 전혀 상관없는 업무영역끼리 잘 나눠야 한다는 것이다...