使用datareader时网络缓冲区可以存储多少数据

Posted

技术标签:

【中文标题】使用datareader时网络缓冲区可以存储多少数据【英文标题】:How much data can be stored in network buffer when datareader is used 【发布时间】:2014-03-21 08:55:09 【问题描述】:

我们都知道 datareader 的工作原理是这样的

数据读取器一次读取一条记录,但它从底层数据库驱动程序中读取它。数据库驱动程序以块的形式从数据库中读取数据,通常使用 8 KB 的缓冲区。

如果您的结果记录很小并且您没有得到很多,它们将全部放入缓冲区中,并且数据库驱动程序将能够将它们全部提供给数据读取器,而无需向数据库询问更多数据.

如果您获取的结果大于缓冲区,您将只能读取它的第一部分,当网络缓冲区中不存在数据时,datareader 将通知 sql server 发送下一个数据块。

这是我们如何使用数据阅读器的小代码

String selectString = "SELECT * FROM PRODUCT";  
    IList<client> clients = new List<client>();  
    using (var selectCommand = new OracleCommand(connection, selectString))  
      
        using (OracleDataReader selectReader = selectCommand.ExecuteReader())  
           
           if (selectReader.HasRows)  
             
               while (selectReader.Read())  
                 
                   clientes.add( GetDomainObject(selectReader) );  
                 
               selectReader.close();  
             
        
      

假设 PRODUCT 表有 10,000 条记录。所以我想知道网络缓冲区一次可以容纳多少数据?

因为当datareader.ExecuteReader() 调用时,读取器将获取一个数据块并存储在该电脑的网络缓冲区中。当datareader.read() 调用时,单个数据将从缓冲区转发到读取器。当所有读取都将从缓冲区读取时,将再次调用数据库并将下一个数据块存储在缓冲区中。

我只是想知道从 db 获取数据时数据读取器可以在缓冲区中存储多少数据。 数据读取器将始终从 db 中获取固定数量的行并存储在缓冲区中,还是取决于缓冲区大小?

缓冲区大小取决于什么......它取决于内存吗?

请仅讨论与网络缓冲区相关的内容,因为我知道数据读取器的工作原理。谢谢

【问题讨论】:

网络缓冲不太可能成为瓶颈...... 而且缓冲区大小不取决于可用的 RAM。这只是一个方便的值,可以防止操作效率极低(即一次发送一个字节的数据)。停止猜测、测试和分析。如果您想查看客户端和服务器之间正在交换哪些数据包,请使用 Wireshark 或其他数据包嗅探器。如果您认为这可能是性能瓶颈,请停止相信并对其进行测试。 【参考方案1】:

根据您的设置阅读此Default Result Set Processing and Multiple Active Result Sets 和Rowsets and SQL Server Cursors

查看TcpClient.ReceiveBufferSize,它会告诉您在一次操作中可以读取多少原始数据。

“ReceiveBufferSize 属性获取或设置您希望在每次读取操作的接收缓冲区中存储的字节数。此属性实际上操纵分配用于接收传入数据的网络缓冲区空间。

您的网络缓冲区应至少与您的应用程序缓冲区一样大,以确保在您调用 NetworkStream.Read 方法时可以获得所需的数据。使用 ReceiveBufferSize 属性设置此大小。如果您的应用程序将接收批量数据,您应该向 Read 方法传递一个非常大的应用程序缓冲区。

如果网络缓冲区小于您在 Read 方法中请求的数据量,您将无法在一次读取操作中检索到所需的数据量。这会导致额外调用 Read 方法的开销。”

然后阅读NetworkStream.Read

此时您将更好地了解问题答案的复杂性。

【讨论】:

仍然不清楚当我使用数据读取器获取 100 条或更多记录时,在一次 db 行程之后可以容纳或存储在网络缓冲区中的数据量。 TcpClient.ReceiveBufferSize 会给我原始大小,从原始大小我怎么能知道网络缓冲区可以存储多少记录。 肯定是记录大小/记录数据大小/tcp 开销的推断。根据微软的说法,默认的 ReceiveBufferSize 是 2^13 或 8192 或 8kbytes。

以上是关于使用datareader时网络缓冲区可以存储多少数据的主要内容,如果未能解决你的问题,请参考以下文章

DataRead 和DataSet区别

Sql 直接从 DataReader 中选择

在 C# 中不使用 ODBC.DataReader 将数据传递给另一个类

最小保证着色器存储块大小是多少?

Java NIO使用及原理分析 来自网上资料整理

从 DataReader 检索 SqlGeography 类型时如何解决 InvalidCastException?