我可以停止调用 sp_reset_connection 以提高性能吗?
我的探查器跟踪显示在每个 sql 批处理或过程调用之间都会调用 exec sp_reset_connection 。有原因,但是我可以阻止它被调用吗?我确信这是不必要的,以提高性能?
更新: 我认为这可以提高性能的原因有两个:
- SQL Server 不需要重置连接状态。我认为这将是一个相对可以忽略不计的改进。
- 减少了网络延迟,因为客户端不需要发送
exec sp_reset_connection
、等待响应,然后发送它真正想要执行的任何 sql。
第二个好处是我感兴趣的,因为在我的架构中,客户端有时距离数据库有一定距离。如果每个 sql 批处理或 rpc 都需要两次往返,则任何网络延迟的影响都会加倍。消除这种双重调用可能会提高性能。
是的,我可以做很多其他事情来提高性能,例如重新设计应用程序,而且我非常热衷于解决问题的根本原因,但在这种情况下,我只想知道这是否可能 以防止调用 sp_reset_connection。然后我可以测试是否有任何性能改进,并正确评估不调用它的风险。
这引发了另一个问题:与 sp_reset_connection 的网络通信是否真的像我上面概述的那样发生?即客户端是否发送exec sp_reset_connection
,等待响应,然后发送真正的sql?或者这一切都归为一块?
My profiler trace shows that exec sp_reset_connection
is being called between every sql batch or procedure call. There are reasons for it, but can I prevent it from being called, if I'm confident that it's unnecessary, to improve performance?
UPDATE:
The reason I imagine this could improve performance is twofold:
- SQL Server doesn't need to reset the connection state. I think this would be a relatively negligible improvement.
- Reduced network latency because the client doesn't need to send down an
exec sp_reset_connection
, wait for response, then send whatever sql it really wants to execute.
The second benefit is the one I'm interested in, because in my architecture the clients are sometimes some distance from the database. If every sql batch or rpc requires a double round-trip this doubles the impact of any network latency. Eliminating such double calls could potentially improve performance.
Yes there are lots of other things I could do to improve performance like re-architect the app, and I'm a big fan of solving the root cause of problems, but in this case I just want to know if it's possible to prevent sp_reset_connection to be called. Then I can test if there is any performance improvement and properly assess the risks of not calling this.
This prompts another question: does the network communication with sp_reset_connection really occur like I outlined above? i.e. Does the client send exec sp_reset_connection
, wait for a response, then send the real sql? Or does it all go in one chunk?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果您使用 .NET 连接到 SQL Server,则从 .NET 3.5 开始禁用额外的重置调用 - 请参阅 此处。 (该财产仍然存在,但它没有任何作用。)
我想微软意识到(就像有人在这里实验中所做的那样)打开门避免重置比获得(可能的)微小的性能提升要危险得多。不能说我责怪他们。
编辑:我错了 - 请参阅此处 - 答案是否定的。
摘要:TDS 消息中设置了一个特殊位,指定应重置连接,SQL Server 会自动执行
sp_reset_connection
。它在 Profiler 中显示为单独的批处理,并且始终在您要执行的实际查询之前执行,因此我的测试无效。<罢工>
是的,它是单独批量发送的。
我编写了一个小 C# 测试程序来演示这一点,因为我很好奇:
启动 Profiler 并将其附加到您选择的实例,过滤我提供的虚拟应用程序名称。然后,在
cmd.ExecuteNonQuery();
行上放置一个断点并运行该程序。第一次跨步时,仅运行查询,等待 5 秒后您得到的只是 SQL:BatchCompleted 事件。当断点第二次到达时,您在分析器中看到的仍然只是一个事件。当您再次跨过去时,您立即会看到
exec sp_reset_connection
事件,然后在延迟后显示 SQL:BatchCompleted 事件。摆脱
exec sp_reset_connection
调用(这对您来说可能是也可能不是合法的性能问题)的唯一方法是关闭 .NET 的连接池。如果您打算这样做,您可能需要构建自己的连接池机制,因为仅将其关闭而不执行其他操作可能会比承受额外往返的影响更大,并且您将拥有手动处理正确性问题。If you're using .NET to connect to SQL Server, disabling of the extra reset call was disabled as of .NET 3.5 -- see here. (The property remains, but it does nothing.)
I guess Microsoft realized (as someone did experimentally here) that opening the door to avoid the reset was far more dangerous than it was to get a (likely) small performance gain. Can't say I blame them.
EDIT: I was wrong -- see here -- the answer is no.
Summary: there is a special bit set in a TDS message that specifies that the connection should be reset, and SQL Server executes
sp_reset_connection
automatically. It appears as a separate batch in Profiler and would always be executed before the actual query you wanted to execute, so my test was invalid.Yes, it's sent in a separate batch.
I put together a little C# test program to demonstrate this because I was curious:
Start Profiler and attach it to your instance of choice, filtering on the dummy application name I provided. Then, put a breakpoint on the
cmd.ExecuteNonQuery();
line and run the program.The first time you step over, just the query runs, and all you get is the SQL:BatchCompleted event after the 5 second wait. When the breakpoint hits the second time, all you see in profiler is still just the one event. When you step over again, you immediately see the
exec sp_reset_connection
event, and then the SQL:BatchCompleted event shows up after the delay.The only way to get rid of the
exec sp_reset_connection
call (which may or may not be a legitimate performance problem for you) would be to turn off .NET's connection pooling. And if you're planning to do that, you'd likely want to build your own connection pooling mechanism, because just turning it off and doing nothing else will probably hurt more overall than taking the hit of the extra roundtrip, and you will have to deal with the correctness issues manually.此问答可能会有所帮助:
Sql Server Profiler 中的“exec sp_reset_connection”是什么意思?
不过,我使用 Entity Framework 和 MS-SQL 2008 R2 进行了快速测试。它表明“exec sp_reset_connection”在第一次调用后并不耗时:
输出是这样的:
所以,最后的结论是:不用担心“exec sp_reset_connection”!它没有浪费任何东西。
This Q/A could be helpful:
What does "exec sp_reset_connection" mean in Sql Server Profiler?
However, I did a quick test using Entity Framework and MS-SQL 2008 R2. It shows that "exec sp_reset_connection" isn't time consuming after the first call:
And output was this:
So, the final conclusion is: Don't worry about "exec sp_reset_connection"! It wastes nothing.
就我个人而言,我会离开它。
鉴于它的作用,我想确保范围内没有临时表或未打开的事务。
公平地说,如果不对生产数据库运行探查器,您将获得更大的性能提升。您是否有任何关于您可以从中获得什么的数字、文章或建议?
Personally, I'd leave it.
Given what it does, I want to make sure I have no temp tables in scope or transactions left open.
To be fair, you will gain a bigger performance boost by not running profiler against your production database. And do you have any numbers or articles or recommendations about what you can gain from this please?
只需保持连接打开,而不是将其返回到池中,并在该连接上执行所有命令。
Just keep the connection open instead of returning it to the pool, and execute all commands on that one connection.