【发布时间】:2013-11-22 14:05:48
【问题描述】:
我意识到我总是按照索引返回的顺序读取我的字段(使用常量)。所以据我了解,我的代码已经与 CommandBehavior.SequentialAccess 兼容。
如果我打开它会有什么好处吗? DataReader 已经是只转发了,只读哪个才是真正的性能提升?
【问题讨论】:
标签: c# sql-server performance ado.net sqldatareader
我意识到我总是按照索引返回的顺序读取我的字段(使用常量)。所以据我了解,我的代码已经与 CommandBehavior.SequentialAccess 兼容。
如果我打开它会有什么好处吗? DataReader 已经是只转发了,只读哪个才是真正的性能提升?
【问题讨论】:
标签: c# sql-server performance ado.net sqldatareader
主要用途是当您读取非常大的 CLOB (nvarchar(max) 等) 或 BLOB (varbinary(max)) 字段时。在默认用法中,它会在让您靠近它之前缓冲整行数据 - 这可能意味着它必须为任何 BLOB / CLOB 字段分配一个大缓冲区。当使用顺序模式时,它不缓冲行;您可以将常规 API 用于小字段(只要您以正确的顺序访问它们),但对于 CLOB / BLOB 字段,您可以使用基于块的 API(GetBytes 和 GetChars)来访问数据依次。例如,通过这样做,您可以仅使用 1k 或 4k 缓冲区来处理 40 MB 的图像。
为 DataReader 提供一种方法来处理包含具有较大二进制值的列的行。 SequentialAccess 不是加载整个行,而是使 DataReader 能够将数据作为流加载。然后,您可以使用 GetBytes 或 GetChars 方法指定开始读取操作的字节位置,以及返回数据的有限缓冲区大小。
【讨论】:
是的,即使不访问 BLOB,使用 CommandBehavior.SequentialAccess 至少应该有一些性能提升。微软知识库文章, An "Invalid attempt to read from column ordinal" error occurs when you use DataReader in Visual C#,声明:
设置 CommandBehavior.SequentialAccess 标志会导致 DataReader 顺序读取行和列。行和列不被缓冲。在您阅读完一列后,它会从内存中删除。任何重新读取列或读取以前读取的列的尝试都会导致异常。
使用 CommandBehavior.SequentialAccess 标志可提供性能优势,尤其是在使用二进制大对象 (BLOB) 字段时。如果不使用 SequentialAccess,所有 BLOB 数据都会复制到客户端。这会消耗大量资源。
CommandBehavior.SequentialAccess 还可以提高访问非 BLOB 字段时的性能。当CommandBehavior.SequentialAccess没有设置时,可以乱序访问一列;但是,您会产生以下开销:
- 检查该列以查看该列是否晚于先前访问的列。
- 检索所有先前访问的列的数据,然后缓存以供以后检索。
必须检查和缓存列,因为当您使用 DataReader 时,底层流对于行和列访问都是只进的。
【讨论】: