NetCore中安裝System.Data.SqlClient4.0.0以上版本就可支援MARS,
簡單測試一下MARS在NetCore中的效能影響
以前,我在ASP.net webform時,有時一個webpage需要有多個datatable,
例如查詢畫面可能會有多個下拉選單和其他資料集,一般處理就需要new 多個connection和sqlcommand,
如下面我查詢三個結果集,並簡單計算總筆數
public async Task QueryMutipleData()
{
string sql1 = @"select top 10 DepartmentID
from Department";
string sql2 = @"select top 20 BusinessEntityID
from Employee";
string sql3 = @"select top 30 AddressID
from Address";
var totals = 0;
using (var sqlConnection = new SqlConnection(_connectionString))
{
if (sqlConnection.State == System.Data.ConnectionState.Closed)
{
await sqlConnection.OpenAsync();
}
var result1 = await sqlConnection.QueryAsync(sql1, commandType: System.Data.CommandType.Text);
totals += result1.AsList().Count;
}
using (var sqlConnection = new SqlConnection(_connectionString))
{
if (sqlConnection.State == System.Data.ConnectionState.Closed)
{
await sqlConnection.OpenAsync();
}
var result1 = await sqlConnection.QueryAsync(sql2, commandType: System.Data.CommandType.Text);
totals += result1.AsList().Count;
}
using (var sqlConnection = new SqlConnection(_connectionString))
{
if (sqlConnection.State == System.Data.ConnectionState.Closed)
{
await sqlConnection.OpenAsync();
}
var result1 = await sqlConnection.QueryAsync(sql3, commandType: System.Data.CommandType.Text);
totals += result1.AsList().Count;
}
await Task.Factory.StartNew<int>(() => totals);
}
可以看到sqlconnection和command我都得各new 三次
但如果啟用MARS(連線字串新增MultipleActiveResultSets=True),
我們就可以共用一條connection,並執行多個批次sqlcommand,如下
public async Task QueryMutipleDataMars()
{
string sql1 = @"select top 10 DepartmentID
from Department";
string sql2 = @"select top 20 BusinessEntityID
from Employee";
string sql3 = @"select top 30 AddressID
from Address";
var totals = 0;
using (var sqlConnection = new SqlConnection(_connectionString))
{
if (sqlConnection.State == System.Data.ConnectionState.Closed)
{
await sqlConnection.OpenAsync();
}
var result1 = await sqlConnection.QueryAsync(sql1, commandType: System.Data.CommandType.Text);
totals += result1.AsList().Count;
var result2 = await sqlConnection.QueryAsync(sql2, commandType: System.Data.CommandType.Text);
totals += result2.AsList().Count;
var result3 = await sqlConnection.QueryAsync(sql3, commandType: System.Data.CommandType.Text);
totals += result3.AsList().Count;
}
await Task.Factory.StartNew<int>(() => totals);
}
啟用MARS我只需要new 一次sqlconnection,其他command都可共用sqlconnection
接下來,我使用jmeter模擬1000條http request,
分別存取QueryMutipleData和QueryMutipleDataMars Action
擷取部分
執行時間結果如下
可以看到,使用MARS共用connection,平均執行時間比New 三個connection進行查詢來的快3倍左右
如果你有類似的需求,或許可以啟用MARS。
補充:針對單一connection和單一command,啟用MARS對查詢效能影響(100條http request)
MARS=true ,三次執行平均:13 , 16 , 13
MARS=false ,三次執行平均:13 , 13 , 15
看來MARS對單一查詢的效能影響不大。
參考
Using MARS with SQL Native Client [Chris Lee]