繁体   English   中英

C#,Sql Server 2008:将大型结果集流式传输给最终用户仅适用于某些数据库

[英]C#, Sql Server 2008: Stream large result set to end user only works on some databases

我有一个长时间运行的查询,返回一个大型数据集。 从Web服务调用此查询,并将结果转换为最终用户的CSV文件。 以前的版本需要10分钟以上才能运行,并且只有在查询完成后才会将结果返回给最终用户。

在大多数情况下,我将查询重写为大约一分钟左右运行的位置,并重写了它的访问方式,以便结果在从数据库服务器进入asp.net Web服务时流式传输到客户端。 我使用SQL Server的本地实例以及没有问题的远程实例对此进行了测试。

现在,在生产部署的尖端,似乎我们的生产SQL服务器机器在查询完成执行之前不会将任何结果发送回Web服务。 此外,我发现另一台机器,与工作(克隆)的远程服务器相同,也不是流式传输结果。

SQL Server 2008的版本在所有计算机上都是相同的。 生产计算机安装的Windows Server版本略有不同(6.0 vs 6.1)。 生产服务器有4个内核,RAM数是其他服务器的几倍。 其他服务器是单核,1GB内存。

是否有任何设置会导致这种情况? 或者是否有任何我可以设置的设置会阻止SQL Server缓冲结果?

虽然我知道这根本不会影响整体运行时间,但它会极大地改变最终用户的感知。

TL;博士; 在查询运行时,我需要将查询的结果流式传输到最终用户。 它适用于某些数据库计算机,但不适用于其他计算机。 所有计算机都运行相同版本的SQL Server。

我在C#中所做的事情的要点:

var reader = cmd.ExecuteReader();
Response.Write(getHeader());
while(reader.Read())
{
  Response.Write(getCSVForRow(reader));
  if(shouldFlush()) Response.Flush()
}

根据以下回复进行澄清

有4个数据库服务器,Local,Prod,QA1,QA2。 它们都在运行SQL Server 2008.它们都加载了相同的数据库(或多或少,非产生1天的延迟)。

Web服务托管在我的机器上(虽然我也测试了远程托管)。

测试之间唯一的变化是web.config中的连接字符串。

QA2正在工作(流式传输),它是QA1(VM)的克隆。 QA1和QA2之间的唯一区别是QA2上添加的数据库与此查询完全无关。

QA1不起作用。

所有测试都包括结果中的最大大小数据集(此时我们限制为5k行)。 第一次刷新发生后,浏览器会显示下载对话框。 这是期望的结果。 我们希望他们知道他们的下载正在处理,即使下载速度很低并且有时下降到零(这是数据库的方式)。

我的冲洗代码目前很简单。 我们刷新每k行, k当前设置为20。

最令人困惑的部分是QA1和QA2表现不同的事实。 我注意到我们的生产服务器设置为兼容模式2005(90),其中QA和本地数据库都设置为2008(100)。 我怀疑这很重要。 当我通过SSMS执行sprocs时,我在所有机器上都有类似的行为。 我立即看到结果流。

是否有任何连接字符串设置可以禁用流媒体?

我所知道的一切都说你正在做的事应该奏效; DataReader和Response.Write()/。Flush()都以“流”方式运行,并且只要有行可以使客户端一次获取一行数据。 响应确实包含一个缓冲区,但是您在每次读/写迭代后将缓冲区推送到客户端,从而最大限度地减少了它的使用。

我将检查Web服务是否配置为正确响应响应中的Flush()命令。 确保生产环境不是Win2008 Server Core安装; Windows Server 2008在某些服务器核心角色中不支持Response.Flush()。 当你期望它们在生产环境中时,我还会检查在ShouldFlush()中评估的条件是否会返回true(您可能正在检查应用程序配置中的值,或者查看IIS设置;我不知道)。

在您的测试中,我会尝试更大的样本数据集; 可能是生产环境暴露了测试环境中也存在的问题,但是使用较小的测试数据集和高速以太网骨干网,与返回数十万行相比,问题并不明显。 DSL。 您可以通过在每次Flush(250)之后插入Thread.Sleep()调用来验证它是否以流式方式工作; 这将减慢服务的执行速度,让您观察响应以每秒4行的速度提供给您的客户端。

最后,确保您在生产环境中使用的客户端设置为以允许流式传输的方式显示CSV文件。 这基本上意味着不应将充当客户端的Web浏览器配置为将文件传递给第三方应用程序。 Web浏览器可以轻松显示通过HTTP传递的文本流; 这就是它的作用,真的。 但是,如果它将流视为CSV文件,并且将其配置为将CSV文件移交给Excel以打开,则浏览器将在调用第三方应用程序之前缓存整个文件。

  1. 将一个新的任务放在任务表中构建这个巨大的CSV文件。
  2. 运行该过程以处理此任务。
  3. 等待结果显示在带有SqlDependency的任务表中。
  4. 将结果返回给客户端。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM