Ror*_*ory 13 sql-server performance sp-reset-connection
我的探查器跟踪显示exec sp_reset_connection在每个sql批处理或过程调用之间调用.这是有原因的,但是如果我确信没有必要提高性能,我可以阻止它被调用吗?
更新:我认为这可以提高性能的原因有两个:
exec sp_reset_connection,等待响应,然后发送它真正想要执行的任何sql.第二个好处是我感兴趣的那个,因为在我的架构中,客户端有时与数据库有一定距离.如果每个sql批处理或rpc都需要双向往返,则会使任何网络延迟的影响加倍.消除这种双重调用可能会提高性能.
是的,我可以做很多其他事情来改善性能,比如重新构建应用程序,我是解决问题根本原因的忠实粉丝,但在这种情况下我只想知道是否可以阻止sp_reset_connection被称为.然后我可以测试是否有任何性能改进,并正确评估不调用它的风险.
这提示了另一个问题:与sp_reset_connection的网络通信是否真的如上所述?即客户端是否发送exec sp_reset_connection,等待响应,然后发送真正的SQL?或者这一切都在一块?
如果您使用.NET连接到SQL Server,则从.NET 3.5开始禁用额外的重置调用 - 请参阅此处.(该财产仍然存在,但它什么也没做.)
我想微软意识到(正如有人在这里做过实验)打开大门以避免重置比获得(可能)小的性能增益要危险得多.不能说我怪他们.
客户端发送
exec sp_reset_connection,等待响应,然后发送真正的SQL?
编辑:我错了 - 看到这里 - 答案是否定的.
简介:TDS消息中设置了一个特殊位,指定应重置连接,并sp_reset_connection自动执行SQL Server .它在Profiler中显示为单独的批处理,并且始终在您要执行的实际查询之前执行,因此我的测试无效.
是的,它是单独发送的.
我整理了一个小小的C#测试程序来证明这一点,因为我很好奇:
using System.Data.SqlClient;
(...)
private void Form1_Load(object sender, EventArgs e)
{
SqlConnectionStringBuilder csb = new SqlConnectionStringBuilder();
csb.DataSource = @"MyInstanceName";
csb.IntegratedSecurity = true;
csb.InitialCatalog = "master";
csb.ApplicationName = "blarg";
for (int i = 0; i < 2; i++)
_RunQuery(csb);
}
private void _RunQuery(SqlConnectionStringBuilder csb)
{
using (SqlConnection conn = new SqlConnection(csb.ToString()))
{
conn.Open();
SqlCommand cmd = new SqlCommand("WAITFOR DELAY '00:00:05'", conn);
cmd.ExecuteNonQuery();
}
}
Run Code Online (Sandbox Code Playgroud)
启动Profiler并将其附加到您选择的实例,过滤我提供的虚拟应用程序名称.然后,在该cmd.ExecuteNonQuery();行上放置一个断点并运行该程序.
第一次跳过时,只运行查询,所有得到的是5秒等待后的SQL:BatchCompleted事件.当断点第二次命中时,你在探查器中看到的只是一个事件.当您再次跳过时,您会立即看到该exec sp_reset_connection事件,然后在延迟后显示SQL:BatchCompleted事件.
摆脱exec sp_reset_connection调用的唯一方法(可能是也可能不是合法的性能问题)将关闭.NET的连接池.如果你打算这样做,你可能想要建立自己的连接池机制,因为只需将其关闭而不做任何其他事情可能会比获得额外往返的更多伤害更多,并且你将拥有手动处理正确性问题.
| 归档时间: |
|
| 查看次数: |
14932 次 |
| 最近记录: |