缓冲参数在Dapper dot net中做了什么?

时间:2012-10-02 20:08:51

标签: .net sqldatareader dapper

Dapper dot net有一个buffer参数(一个bool),但据我所知,它会将结果转换为一个列表,然后再返回它。< / p>

根据documentation

  

Dapper的默认行为是执行你的sql并缓冲整个   读者回来了。这在大多数情况下是理想的,因为它最小化共享   锁定数据库并减少数据库网络时间。

     

但是,在执行大量查询时,您可能需要最小化内存   足迹,只根据需要加载对象。为此,传递,缓冲:   在Query方法中为false。

我不确定如何将结果转换为列表来完成此操作。我错过了什么吗?我唯一的想法是,应该将CommandBehavior的{​​{1}}设置为ExecuteReader(但事实并非如此)。

3 个答案:

答案 0 :(得分:48)

  

但据我所知,它唯一能做的就是在返回之前将结果转换为列表

你没有遗漏任何东西。这是关键的区别。除非它不是强制转换:实际返回的对象是非常不同的。基本上,有两种方法可以读取数据:

  • 在流API中,每个元素都是单独生成的;这是非常高效的内存,但是如果你对每个项目进行大量的后续处理,则意味着你的连接/命令可以长时间“活动”
  • 在缓冲的API中,在产生任何内容
  • 之前,所有行都被读取

如果您正在读取大量数据(数千到数百万行),则可能更喜欢非缓冲API。否则会使用大量内存,即使第一行可用,也可能会有明显的延迟。但是,在大多数常见情况下,读取的数据量都在合理的限制范围内,因此在将其传递给调用者之前将其推入列表是合理的。这意味着命令/阅读器等已经完成 之前返回。

作为旁注,缓冲模式也避免了那么常见的“连接上已经有一个开放的阅读器”(或者无论确切的措辞是什么)。

答案 1 :(得分:6)

我不得不对@ chris-marisic不同意......我遇到了多个&#34; Out Of Memory&#34;使用 buffered:true 时,在该确切行(data.ToList())处的异常。它不是一个&#34; zillion行X bazillion列&#34;查询,只是一个常规的5-6k行SQL结果,大约有30列。

这实际上取决于您的配置。例如。您的SQL和IIS是否在同一台物理计算机上运行。 IIS机器上安装了多少内存,页面文件设置是什么等。如果Web服务器有2 GB或更少 - 请考虑设置&#34;缓冲:false&#34;对于超重报道。

答案 2 :(得分:4)

在实践中,最好从不使用 buffered: false

我发现读取甚至数百万行,使用缓冲结果比使用缓冲结果更快,内存效率更高。如果你的表有500列你正在读取数百万或数百万行,那么也许存在交叉点。

如果您的结果集小于数十亿的值,则无法以任何理由使用buffered: false

在实际分析中,我感到震惊的是,在标准缓冲模式下,从Sql Server读取千兆字节数据的速度更快(快2-6倍),内存效率更高。性能提升甚至可以解释可能的最小操作,通过索引将对象添加到稀疏数组中,而不是调整大小。使用从无缓冲到缓冲的多千兆字节稀疏阵列切换,可以将负载时间提高2倍。使用buffered写入字典时,在插入数百万条记录时,加载时间增加了6倍(字典使用表的int PK作为密钥,以便尽可能计算哈希码的基本值。)

与所有关于表现的事情一样,你总是要分析。但是,我可以非常高的确定性告诉你始终以Dapper的默认缓冲行为开始。