다중 활성 결과 집합(MARS) 설명 및 사용 예
한대성
SQL Server MVP
에이디컨설팅 책임 컨설턴트 | SQLLeader.com 운영자
SQL Serve 2005의 여러 새로운 기능들 중에서 MARS라는 것이 있습니다. MARS는 Multiple Active Result Sets의 약자로 한국말로는 “다중 결과 집합” 또는 “다중 활성 결과 집합”으로 번역되어 있습니다.
이 기능에 대해 간단히 요약하자면, 하나의 연결만을 이용해서 여러 개의 배치 쿼리를 실행할 수 있다는 것입니다.
SQL Server 2005 이전에는 다음과 같이 하나의 연결에는 하나의 배치 쿼리만 실행할 수 있었습니다.
A. MARS 미사용 형태
[C#]
private void MARS_Off()
{
SqlConnection conn = new SqlConnection("Server=serverName;Database=adventureworks;Trusted_Connection=yes;");
string sql1 = "SELECT * FROM [Person].[Address]";
string sql2 = "SELECT * FROM [Production].[TransactionHistory]";
SqlCommand cmd1 = new SqlCommand(sql1, conn);
SqlCommand cmd2 = new SqlCommand(sql2, conn);
cmd1.CommandTimeout = 500;
cmd2.CommandTimeout = 500;
conn.Open();
SqlDataReader dr1 = cmd1.ExecuteReader();
conn.Close();
'conn 연결을 이용하여 다른 쿼리를 실행하기 위해서는 반드시 연결을 닫아주고 다시 열어야 합니다.
conn.Open();
SqlDataReader dr2 = cmd2.ExecuteReader();
conn.Close();
}
|
[VB.net]
Private Sub MARS_Off()
Dim conn As New SqlClient.SqlConnection("Server=serverName;Database=adventureworks;Trusted_Connection=yes;")
Dim sql1 As String = "SELECT * FROM [Person].[Address]"
Dim sql2 As String = "SELECT * FROM [Production].[TransactionHistory]"
Dim Cmd1 As New SqlClient.SqlCommand(sql1, conn)
Dim Cmd2 As New SqlClient.SqlCommand(sql2, conn)
Cmd1.CommandTimeout = 500
Cmd2.CommandTimeout = 500
conn.Open()
Cmd1.ExecuteReader()
conn.Close()
'conn 연결을 이용하여 다른 쿼리를 실행하기 위해서는 반드시 연결을 닫아주고 다시 열어야 합니다.
conn.Open()
Cmd2.ExecuteReader()
conn.Close()
End Sub
|
이와 같은 형태의 프로그램을 실행시킨 후, 프로파일러를 이용해서 수행된 쿼리를 확인하면 다음과 같습니다.
즉, SELECT * FROM [Person].[Address]라는 쿼리를 conn 이라는 연결을 통해 수행한 후 또는 사용 중(Data Fetch)인 상태에서 다른 쿼리를 실행하기 위해서는 반드시 연결을 닫고 다시 열어서 사용해야 합니다. 만약, 위의 스크립트에서 conn.Close()와 Conn.Open() 부분을 수행하지 않고 바로 실행할 경우, 다음과 같은 에러가 발생합니다.
위의 프로파일러 결과와 같이 연결을 닫고 새로 여는 동작은 Audit Login과 Audio Logout 이벤트를 발생시키는 부하가 큰 작업이며, 이러한 형태가 자주 수행될 경우에는 성능이 나빠질 수도 있습니다.
B. MARS 사용 형태
MARS를 사용하기 위해서는 연결 문자열에 MultipleActiveResultSets=true이라는 옵션을 추가하면 됩니다.
[C#]
private void MARS_Off()
{
SqlConnection conn = new SqlConnection("Server=serverName;Database=adventureworks;” & _
“Trusted_Connection=yes;MultipleActiveResultSets=true;")
string sql1 = "SELECT * FROM [Person].[Address]";
string sql2 = "SELECT * FROM [Production].[TransactionHistory]";
SqlCommand cmd1 = new SqlCommand(sql1, conn);
SqlCommand cmd2 = new SqlCommand(sql2, conn);
cmd1.CommandTimeout = 500;
cmd2.CommandTimeout = 500;
conn.Open();
SqlDataReader dr1 = cmd1.ExecuteReader();
'conn 연결을 닫지 않은 상태에서 다른 쿼리를 실행합니다
SqlDataReader dr2 = cmd2.ExecuteReader();
conn.Close();
}
|
[VB.net]
Private Sub MARS_Off()
Dim conn As New SqlClient.SqlConnection("Server=serverName;Database=adventureworks;” & _
“Trusted_Connection=yes;MultipleActiveResultSets=true;")
Dim sql1 As String = "SELECT * FROM [Person].[Address]"
Dim sql2 As String = "SELECT * FROM [Production].[TransactionHistory]"
Dim Cmd1 As New SqlClient.SqlCommand(sql1, conn)
Dim Cmd2 As New SqlClient.SqlCommand(sql2, conn)
Cmd1.CommandTimeout = 500
Cmd2.CommandTimeout = 500
conn.Open()
Cmd1.ExecuteReader()
'conn 연결을 닫지 않은 상태에서 다른 쿼리를 실행합니다
Cmd2.ExecuteReader()
conn.Close()
End Sub
|
위의 스크립트에서와 같이 하나의 연결을 이용하여 여러 배치 쿼리를 수행할 수 있습니다.
본 글에서는 MARS를 구현하는 방법에 대해서만 간략히 설명하였습니다. 실제 환경에서 이를 적용하기 위해서는 충분한 테스트와 성능 확인 작업을 수행해야 합니다. 이 외에 추가적인 정보나 자세한 사항을 확인하고자 할 경우, 다음 링크를 참고하시기 바랍니다.
ms-help://MS.SQLCC.v9/MS.SQLSVR.v9.ko/udb9/html/63fd230a-7928-4979-82f3-6b7b0b924f13.htm
http://www.sqlteam.com/item.asp?ItemID=26926
|