CommandBehavior.SequentialAccess是否有性能提升?涉及IT技术。

13

我意识到我总是按照索引的顺序(使用常量)读取我的字段。因此,就我所理解的而言,我的代码已经与CommandBehavior.SequentialAccess兼容。

如果我开启它,会有什么好处吗?DataReader已经是只向前、只读的,这才是真正的性能提升吧?

2个回答

18
这个的主要用途是在读取非常大的CLOB(例如nvarchar(max))或BLOB(varbinary(max))字段时。在默认使用情况下,它会在让您接近数据之前缓冲整个行 - 这可能意味着必须为任何BLOB / CLOB字段分配大缓冲区。当使用顺序模式时,它不会缓冲该行; 对于小字段,您可以使用常规API(只要按正确顺序访问它们),但对于CLOB / BLOB字段,您可以使用基于块的API(GetBytesGetChars)依次访问数据的一部分。通过这样做,您可以仅使用1k或4k缓冲区处理40 MB图像等大文件。 MSDN说的也一样 提供了一种让DataReader处理包含大二进制值列的行的方式。与其加载整个行不同,SequentialAccess使DataReader能够将数据作为流加载。然后,您可以使用GetBytes或GetChars方法指定要开始读取操作的字节位置,以及返回数据的有限缓冲区大小。

1
其实,现在我想起来了 - 在这里,一个 8040 字节(或其倍数)的缓冲区是很正常的。如果我没记错的话,由于 SQL Server 中的页面大小为 8040,如果您努力完成页面,则往往会获得最佳结果。 - Marc Gravell
如果使用FileStream来处理BLOB,SQL页面缓冲区的大小是否仍然需要考虑?我的理解是文件内容存储在NTFS文件系统中。 - Issa Fram

11

是的,使用CommandBehavior.SequentialAccess应该会有一些性能提升,即使不访问BLOB。微软KB文章,在Visual C#中使用DataReader时出现“尝试从列序数读取时发生无效尝试”错误,指出:

设置CommandBehavior.SequentialAccess标志会导致DataReader按顺序读取行和列。行和列不会被缓存。当您读取超过某一列时,它将从内存中删除。任何尝试重新读取该列或读取先前已读取的列都会导致异常。使用CommandBehavior.SequentialAccess标志可以提高性能,特别是在使用二进制大对象(BLOB)字段时。如果不使用SequentialAccess,则所有BLOB数据都将被复制到客户端。这可能会消耗大量资源。CommandBehavior.SequentialAccess还在访问非BLOB字段时提高了性能。当未设置CommandBehavior.SequentialAccess时,可以按任意顺序访问列;但是,需要承担以下开销: - 检查该列是否晚于先前访问的列。 - 检索所有先前访问的列的数据,然后将其缓存以便以后检索。 必须检查和缓存列,因为当使用DataReader时,底层流对于行和列访问都是单向的。

4
我的团队测得阅读器基于所有的访问性能提高了2倍。我们的数据访问层代码被设置为始终执行顺序读取和显式列顺序。如果您这样做,这个选项应该是默认行为。感谢您的提示! - Matthew Hazzard
@MatthewHazzard 太棒了!是啊,我想不出不使用SequentialAccess的理由。除非你总是通过列名访问它们,否则很少需要在列之间来回移动,这样可能会很容易地导致顺序混乱。很高兴它对你有帮助,也感谢你分享它如何为你工作。 - Solomon Rutzky

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接