如果您使用 .NET 连接到 SQL Server,则从 .NET 3.5 开始禁用额外的重置调用 - 请参见此处。(该属性仍然存在,但它什么也不做。)
我猜微软意识到(就像有人在这里做实验一样)打开门来避免重置比获得(可能的)小的性能提升要危险得多。不能说我怪他们。
客户端是否发送exec sp_reset_connection
,等待响应,然后发送真正的 sql?
编辑:我错了——看这里——答案是否定的。
摘要:TDS 消息中设置了一个特殊位,指定应重置连接,SQL Server 将sp_reset_connection
自动执行。它在 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();
}
}
启动 Profiler 并将其附加到您选择的实例,过滤我提供的虚拟应用程序名称。然后,在该行上放置一个断点cmd.ExecuteNonQuery();
并运行程序。
第一次跨步时,只运行查询,在等待 5 秒后得到的只是 SQL:BatchCompleted 事件。当断点第二次命中时,您在分析器中看到的仍然只是一个事件。再次跨步时,立即看到该exec sp_reset_connection
事件,然后延迟后出现 SQL:BatchCompleted 事件。
摆脱exec sp_reset_connection
调用的唯一方法(这对您来说可能是也可能不是合法的性能问题)是关闭 .NET 的连接池。如果您打算这样做,您可能希望建立自己的连接池机制,因为仅将其关闭并且不做任何其他事情可能会比承受额外往返的冲击更大,而且您将拥有手动处理正确性问题。