SqlCommand.Cancel() 会导致性能提升吗?
我已经看到它出现在代码中的多个位置,从来没有解释,只是上面有一个神秘的注释(声明和执行包括上下文概念。这只是运行 SqlCommand 的标准过程):
//SqlCommand cmd = new SqlCommand();
//cmd.ExecuteReader();
//Read off the results
//Cancel the command. This improves query time.
cmd.Cancel ();
基本上,在完成查询后,它返回并取消它,声称性能有所提升。我想当它消失并释放 XmlReader 时您可能会收回一些内存,但通常它无论如何都会超出范围。
我以前从未关心过它,但它最终出现在我正在审查的一些代码中。 在代码中运行 SqlCommand 后取消它实际上是否会以某种方式加速它,或者这只是一些奇怪的程序员迷信?
I have seen this show up several places in code, never with an explanation, just a cryptic comment above it (Declaration and execution included for an idea of context. It's just a standard procedure of running a SqlCommand):
//SqlCommand cmd = new SqlCommand();
//cmd.ExecuteReader();
//Read off the results
//Cancel the command. This improves query time.
cmd.Cancel ();
Basically, after finishing a query, it goes back and cancels it, claiming some performance boost. I suppose you might get some memory back when it goes and frees up the XmlReader, but usually it's about to go out of scope anyways.
I've never bothered with it before, but it's finally showed up in some code I'm reviewing. Does canceling a SqlCommand after running it in the code actually somehow speed it up, or is this just some weird programmer superstition?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
根据 MSDN,这是正确的。
诡异的!
According to MSDN, this is correct.
Weird!
如果您调用
ExecuteReader
返回大量行,并且您不读取数据,则调用Cancel
可能会大幅提高性能所有行。为了说明这一点,假设一个查询返回一百万行,并且您在读取前 1000 行后关闭读取器。如果您在关闭读取器之前未能调用
Cancel
,则Close
方法将在内部枚举剩余 999,000 行时发生阻塞尝试看看!
Calling
Cancel
gives a potentially MASSIVE performance improvement if your call toExecuteReader
returns a large number of rows, and you don't read all the rows.To illustrate, let's say a query returns a million rows, and you close the reader after reading just the first 1000 rows. If you fail to call
Cancel
before closing the reader, theClose
method will block while it internally enumerates through the remaining 999,000 rowsTry it and see!
我们 Cinchcast 的技术团队做了一些基准测试,我们发现添加 cmd.Cancel() 实际上会减慢速度。
我们有一个 DALC 调用,用于获取主持人的剧集列表。
我们运行了 1000 次,得到了返回 10 集的平均响应时间。
所以返回 10 场演出
平均取消时间:0.069s
没有取消的平均:0.026s
当返回 10 集运行时速度明显慢一些。
因此,我再次尝试返回 100 集,看看更大的结果集是否会产生影响。
因此每次调用都会返回 100 个节目
平均取消时间:0.132s
没有取消的平均时间:0.122s
所以这次时间差异要小得多。尽管在我们通常的用例中不使用“取消”,但它仍然更快。
Our Tech team at Cinchcast did some benchmarking, and we have found that adding the cmd.Cancel() actually slows it down.
We have a DALC call that gets a list of episodes for a host.
We ran it 1000 times and got the average response time to return 10 episodes.
So with returning 10 shows
Average With Cancel: 0.069s
Average Without Cancel : 0.026s
Pretty significantly slower when running with returning 10 episode.
So, I tried again with returning 100 episodes to see if a larger result set makes a difference.
So with returning 100 shows on each call
Average With Cancel: 0.132s
Average Without Cancel : 0.122s
So this time the difference in time was much less. It is still faster though without using the Cancel for our usual use cases.
在您的示例中,您打开阅读器,读取所有行,然后取消命令,但您没有显示阅读器关闭的位置。
确保取消发生在
Dispose
/Close
之前。例如,在此示例中您不会获得性能提升(不幸的是,生产中的真实代码):太糟糕了,它已经被Using语句关闭了!
这就是它应该如何阅读以实现潜力好处:
来自 MSDN SqlCommand.Cancel:
In your example, you open the reader, read all the rows, and the Cancel the command, but you didn't show where the reader was being closed.
Make sure the canceling happens before the
Dispose
/Close
. For example, you wouldn't get a performance boost in this example (real code in production, unfortunately):Too bad it's already closed by the Using Statement!
This is how it should read to realize the potential benefit:
From MSDN SqlCommand.Cancel: