병렬로 쿼리 실행하기
Microsoft Premier Field Engineer
한대성
Question |
같은 프로시져를 동시에 여러 프로세스로 실행하고 싶습니다. 아이디어가 안 떠 오르는데, SSIS 로 할 수 있는 방법 없을까요? |
같은 프로시저를 동시에 실행시킨다는 것은 간단해 보이지만 꽤 까다로운 주제입니다.
SQL 쿼리 실행 자체가 동기성 작업(Synchronous)이라, 쿼리 분석기이든 다른 어플리케이션이든 쿼리를 실행시키고 결과가 나올 때 까지 기달려야 하는 형태입니다. 이에 반해 SQL Agent의 작업과 같은 형태는 비동기성 작업(Asynchronous)이라 할 수 있습니다. 시작만 시켜놓고 종료 여부에 상관없이 다른 작업들을 할 수 있는 형태입니다.
SSIS를 이용해서 동시에 여러 작업을 수행하도록 하는 것을 어떻게든 구현해 봅시다.
어떻게 패키지를 구성할 것이냐. 10개 동시에 수행하는 것으로 단순화 해서 설명드리겠습니다.
10개의 SQL 실행 작업을 만들어놓고선, 각 실행 작업들이 수행할 변수를 지정합니다. 변수도 물론 10개가 되겠지요. 파일이든 테이블이든간에 어디선가 쿼리 목록을 읽어온 다음(1), 차례대로 이 변수들에 대입시켜주고선 SQL 실행 작업들을 실행시키는 것이지요.(2)
1. 쿼리 목록을 읽어와서 변수에 대입하기.
본 예에서는 다음과 같은 형태의 쿼리가 저장된 파일에서 쿼리를 읽어오도록 구성하겠습니다.
SSIS에서 QueryObj이라는 이름의 Object형 변수를 하나 추가한 다음, 아래와 같이 데이터 흐름 작업에서 RecordSet 대상을 이용하여 이 변수에 결과값을 저장하는 것을 구성합니다. RecordSet 대상 편집기에서 저장할 변수를 지정한 후, 입력 열 탭에서 저장되는 열을 선택하셔야 합니다.
이제 SSIS 변수에 Query1, Query2, .. Query10 이라는 10개의 String 형 변수를 추가합니다.
데이터 흐름 작업 뒤에 스크립트 작업을 연결한 후, 아래와 같이 변수들을 지정합니다.
스크립트 편집기를 연 다음 상단의 프로젝트(P) à 참조 추가(R)을 선택한 후, System.Xml.dll 을 참조로 추가합니다.
다음과 같은 스크립트를 입력합니다.
Imports System Imports System.Data Imports System.Math Imports Microsoft.SqlServer.Dts.Runtime Imports System.IO
Public Class ScriptMain
Public Sub Main()
Dim oLead As New Data.OleDb.OleDbDataAdapter Dim dt As New Data.DataTable Dim dr As System.Data.DataRow Dim seq As Integer = 0
oLead.Fill(dt, Dts.Variables("QueryObj").Value)
For Each dr In dt.Rows
seq += 1 Dts.Variables("Query" & seq.ToString).Value = dr.Item(0).ToString Next Dts.TaskResult = Dts.Results.Success
End Sub End Class
|
2. SQL 실행 작업 구성하기
이제 시퀀스 컨테이너를 스크립트 작업 뒤에 연결한 후, 시퀀스 컨테이너 안에 10개의 SQL 실행 작업을 추가합니다.
각각의 SQL 실행작업을 열어 실행할 DB 연결을 지정하고, 각 작업들의 속성 중 Expressions을 선택하여 아래와 같이 SQLStatementSource 속성에 대해 Query1 부터 Query10까지 지정합니다.
각 작업의 속성 중 DelayValidation 속성도 True로 바꿔줍니다. (필수 사항은 아닙니다.)
그런 다음, 패키지의 빈 곳을 선택한 후, 속성의 MaxConcurrentExecutables 값을 10으로 변경해 줍니다. 동시에 수행할 수 있는 작업의 수를 10개로 하겠다라는 것입니다.
완성된 모습은 다음과 같습니다.
아래와 같은 테스트 프로시저를 이용하여 결과를 확인해 봅시다.
USE TEMPDB GO
CREATE TABLE ResultValues ( seq int, insdate datetime default(getdate()) ) GO
CREATE PROC TestProc(@seq int) as INSERT ResultValues(seq) values(@seq) WAITFOR DELAY '00:00:01' GO |
10개의 SQL 실행 작업을 동시에 수행하라고는 하였지만, 위의 결과와 같이 약간의 차이가 존재하긴 합니다.
참고삼아 다음과 같이 SQL 쿼리를 이용하여 수행하였을 때의 결과를 비교해 봅시다.
만약, 반드시 동일한 시간에 동시에 수행해야 한다면?
SSIS 패키지에서 이를 제어하지 말고, 저장 프로시저를 약간 고쳐서 이를 해결해 봅시다.
ALTER PROC TestProc(@seq int, @WAITTIME DATETIME = NULL) as
IF @WAITTIME IS NOT NULL WAITFOR TIME @WAITTIME
INSERT ResultValues(seq) values(@seq) WAITFOR DELAY '00:00:01' GO |
그리고선, 실행 쿼리문도 다음과 같이 변경합니다.
EXEC dbo.TestProc 1,'2009-08-07 23:17:00.000' EXEC dbo.TestProc 2,'2009-08-07 23:17:00.000' EXEC dbo.TestProc 3,'2009-08-07 23:17:00.000' EXEC dbo.TestProc 4,'2009-08-07 23:17:00.000' EXEC dbo.TestProc 5,'2009-08-07 23:17:00.000' EXEC dbo.TestProc 6,'2009-08-07 23:17:00.000' EXEC dbo.TestProc 7,'2009-08-07 23:17:00.000' EXEC dbo.TestProc 8,'2009-08-07 23:17:00.000' EXEC dbo.TestProc 9,'2009-08-07 23:17:00.000' EXEC dbo.TestProc 10,'2009-08-07 23:17:00.000' |
'연구개발 > DTS & SSIS' 카테고리의 다른 글
비표준화된 입력 데이터에 대한 처리 (0) | 2011.08.27 |
---|---|
패키지 실행 시 매개변수 동적으로 주기 (0) | 2011.08.27 |
문자열의 코드 변환하기 (0) | 2011.08.27 |
패키지 외부에서 매개 변수 값 지정하기 (0) | 2011.08.27 |
FTP 작업에서 여러 파일 보내기 (0) | 2011.08.27 |