簡體   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