C# SqlCommand.Cancel()是否会提高性能?
我在代码中看到过几个地方,从来没有解释过,上面只有一条隐晦的注释(声明和执行是为了了解上下文。这只是运行SqlCommand的一个标准过程): 基本上,在完成一个查询后,它会返回并取消它,从而提高性能。我想当它运行并释放XmlReader时,您可能会得到一些内存,但通常它无论如何都会超出范围 我以前从来没有用过它,但它最终出现在我正在审阅的一些代码中在代码中运行SqlCommand后取消它是否真的以某种方式加快了速度,或者这只是一些奇怪的程序员迷信?根据,这是正确的 Close方法将填充这些值 对于输出参数,返回值 和RecordsAffected,增加了 关闭一个应用程序所需的时间 用于处理的SqlDataReader 大型或复杂的查询。当 返回值和 不支持受查询影响的记录 重要的是,它需要的时间 关闭SqlDataReader可以减少 通过调用 之前关联的SqlCommand对象 调用Close方法C# SqlCommand.Cancel()是否会提高性能?,c#,sqlcommand,C#,Sqlcommand,我在代码中看到过几个地方,从来没有解释过,上面只有一条隐晦的注释(声明和执行是为了了解上下文。这只是运行SqlCommand的一个标准过程): 基本上,在完成一个查询后,它会返回并取消它,从而提高性能。我想当它运行并释放XmlReader时,您可能会得到一些内存,但通常它无论如何都会超出范围 我以前从来没有用过它,但它最终出现在我正在审阅的一些代码中在代码中运行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 ();
}