>执行几个查询(通常为20-50,但最多为100-200),这些查询都具有从xyz的some_table顺序中选择a,b,…的形式.有一个符合该查询的索引,因此结果应该或多或少可用而无需任何计算.
>逐步消耗结果.确切的步进取决于结果,因此它不是完全可预测的.
>通过逐步调整结果来汇总一些结果.我只会消耗结果的第一部分,但无法预测我需要多少.停止标准取决于算法内的某个阈值.
我的想法是打开几个sqlDataReader,但我有两个问题:
>每个连接只能有一个sqlDataReader,在CLR方法中我只有一个连接 – 据我所知.
>我不知道如何告诉sqlDataReader如何以块的形式读取数据.我找不到sqlDataReader应该如何表现的文档.据我所知,它正在准备整个结果集,并将整个结果加载到内存中.即使我只消耗它的一小部分.
任何提示如何解决这个问题作为CLR方法?或者是否有更低级别的sql服务器接口,更适合我的问题?
更新:我应该更明确地提出两点:
>我在谈论大数据集,因此查询可能会产生1 mio记录,但我的算法只会消耗前100-200个记录.但正如我之前所说:我事先并不知道确切的数字.
>我知道sql可能不是那种算法的最佳选择.但由于其他限制,它必须是sql服务器.所以我正在寻找最好的解决方案.
解决方法
SqlDataReader
没有读取整个数据集,你将它与
Dataset
类混淆.它会逐行读取,因为正在调用.Read()方法.如果客户端不使用结果集,则服务器将暂停查询执行,因为它没有空间将输出写入(所选行).当客户端消耗更多行(正在调用sqlDataReader.Read)时,执行将恢复.甚至还有一个特殊的命令行为标志
SequentialAccess
,它指示ADO.Net不要在内存中预加载整行,这对于以流方式访问大型BLOB列很有用(实际例子见
Download and Upload images from SQL Server via ASP.Net MVC).
当MARS处于活动状态时,您可以在单个连接上激活多个活动结果集(sqlDataReader).但是,MARS与sqlCLR上下文连接不兼容.
因此,您可以创建CLR streaming TVF来完成CLR中所需的一些操作,但前提是您只有一个SQL查询源.要求您放弃上下文连接和使用的多个查询并不是完全成熟的连接,即.在环回中连接回同一个实例,这将允许MARS,从而消耗多个结果集.但是loopback有自己的问题,因为它打破了你从上下文连接中获得的事务边界.特别是使用环回连接,您的TVF将无法读取由调用TVF的同一事务所做的更改,因为在不同的连接上是不同的事务.