C# SqlCommand.Cancel()是否会提高性能?

C# SqlCommand.Cancel()是否会提高性能?,c#,sqlcommand,C#,Sqlcommand,我在代码中看到过几个地方,从来没有解释过,上面只有一条隐晦的注释(声明和执行是为了了解上下文。这只是运行SqlCommand的一个标准过程): 基本上,在完成一个查询后,它会返回并取消它,从而提高性能。我想当它运行并释放XmlReader时,您可能会得到一些内存,但通常它无论如何都会超出范围 我以前从来没有用过它,但它最终出现在我正在审阅的一些代码中在代码中运行SqlCommand后取消它是否真的以某种方式加快了速度,或者这只是一些奇怪的程序员迷信?根据,这是正确的 Close方法将填充这些值

我在代码中看到过几个地方,从来没有解释过,上面只有一条隐晦的注释(声明和执行是为了了解上下文。这只是运行SqlCommand的一个标准过程):

基本上,在完成一个查询后,它会返回并取消它,从而提高性能。我想当它运行并释放XmlReader时,您可能会得到一些内存,但通常它无论如何都会超出范围

我以前从来没有用过它,但它最终出现在我正在审阅的一些代码中在代码中运行SqlCommand后取消它是否真的以某种方式加快了速度,或者这只是一些奇怪的程序员迷信?

根据,这是正确的

Close方法将填充这些值 对于输出参数,返回值 和RecordsAffected,增加了 关闭一个应用程序所需的时间 用于处理的SqlDataReader 大型或复杂的查询。当 返回值和 不支持受查询影响的记录 重要的是,它需要的时间 关闭SqlDataReader可以减少 通过调用 之前关联的SqlCommand对象 调用Close方法


奇怪

我们在Cinchcast的技术团队做了一些基准测试,我们发现添加cmd.Cancel()实际上会减慢速度

我们有一个DALC呼叫,它可以获取一个主持人的剧集列表。 我们运行了1000次,得到了返回10集的平均响应时间

因此,随着10场演出的回归 取消时的平均值:0.069秒 未取消的平均值:0.026s

在返回10集时,运行速度明显较慢

所以,我再次尝试返回100集,看看一个更大的结果集是否会有所不同

因此,每次通话返回100个节目 取消时的平均值:0.132s 未取消的平均值:0.122s


所以这一次时间上的差异要小得多。尽管在我们通常的用例中不使用取消,但速度仍然更快。

如果调用
取消
返回大量行,而您没有读取所有行,则可能会大大提高性能

举个例子,假设一个查询返回一百万行,您只读取了前1000行就关闭了读卡器。如果在关闭读卡器之前未能调用
Cancel
,则
Close
方法将阻塞,同时在内部枚举剩余的999000行


试试看

在您的示例中,您打开读卡器,读取所有行,然后单击“取消”命令,但没有显示关闭读卡器的位置

确保在
Dispose
/
关闭之前执行取消操作。例如,在本例中,您无法获得性能提升(不幸的是,实际生产代码):

太糟糕了,它已经被Using语句关闭了

以下是实现潜在利益的阅读方式:

using (var rdr = cmd.ExecuteReader (CommandBehavior.Default))
{
   retval = DocumentDir.DBRead (rdr);

   // Optimization.  Allows reader to close more quickly.
   cmd.Cancel ();
}
发件人:

在某些罕见的情况下,如果在调用Cancel之前调用ExecuteReader然后调用Close(隐式或显式),然后调用Cancel,则Cancel命令将不会发送到SQL Server,并且结果集可以在调用Close后继续流式处理。
为避免这种情况,确保在关闭读卡器或连接之前调用Cancel


呵呵。没有想到要查看SqlDataReader文档。抢手货看一下底层代码,很明显它在Close上做了大量的工作,但是,我一刻也不认为这在一天结束时有那么重要。学到了一些东西;-)虽然我同意你必须在DB IO上受到严重限制才能注意到这个变化。@Lucas Heneks,谢谢你发布这个报价。我认为需要注意的是,cmd.Cancel()告诉SQL Server不要发回输出参数、返回值或RecordsAffected。通常,您会将nocount设置为on以禁用发回RecordsAffected,如果存在输出参数或返回值,您可能希望检索它们,因此我想知道该技术在大多数情况下有多适用。您分析过代码吗?看看它到底有多大的影响是很有趣的。有一个重要的边缘案例,调用Cancel会产生很大的不同——请看下面我的答案——不能过分低估“不读取所有行”是这个方法的主要功能。
using (var rdr = cmd.ExecuteReader (CommandBehavior.Default))
{
   retval = DocumentDir.DBRead (rdr);
}

// Optimization.  Allows reader to close more quickly.... NOT!
cmd.Cancel ();  // bad!
using (var rdr = cmd.ExecuteReader (CommandBehavior.Default))
{
   retval = DocumentDir.DBRead (rdr);

   // Optimization.  Allows reader to close more quickly.
   cmd.Cancel ();
}