共用方式為


針對ASYNC_NETWORK_IO等候類型所產生的慢速查詢進行疑難解答

徵狀

當 SQL Server 產生結果集,並將結果放入輸出緩衝區,並將結果傳送至用戶端應用程式時,用戶端應用程式會從輸出緩衝區擷取結果集。 如果用戶端應用程式停止或擷取結果的速度不夠快,SQL Server 必須等候用戶端應用程式已收到所有結果,再傳送更多結果。 這個等候會顯示為 ASYNC_NETWORK_IO。 如需詳細資訊,請參閱瞭解 SQL Server 中ASYNC_NETWORK_IO等候的影片

過度ASYNC_NETWORK_IO等候可能會造成兩個問題:

  • 查詢可能會變慢,因為其總持續時間會更長。

  • 當 SQL Server 等候用戶端擷取結果時,無法釋放取得的鎖定。 如果鎖定長時間未釋出,其他會話將會在 SQL Server 上遭到封鎖。

原因和解決方式

下列各節列出此等候類型的常見原因,以及解決問題的對應步驟:

大型結果集

某些應用程式用戶端會要求數千個或甚至數百萬個數據列,然後套用篩選、排序和匯總來處理結果。 大型結果集可能會導致不必要的網路使用率和用戶端應用程式處理。

解析度:應用程式開發人員必須仔細平衡 SQL Server 與客戶端之間的處理。 篩選或匯總可由 SQL Server 執行,而最終結果集可能很小。 限制送達客戶端的結果集。 收到數據之後,用戶端上對數據、簡報和格式設定的計算就更適當。

應用程式擷取結果的速度不夠快

如果用戶端應用程式擷取結果的速度不夠快,且未通知 SQL Server 已收到結果集,ASYNC_NETWORK_IO則會在伺服器上進行等候。

為了說明如何使用 ADO.NET,根據預設,DataSetDataTable 會先擷取所有數據列以完成,用戶端才能存取它。 不過, SqlDataReader 之類的類別可讓應用程式開發人員在從伺服器擷取每個數據列之後,選擇該怎麼做。 應用程式可以一次擷取一個數據列,然後根據商務需求處理此數據列。 例如:

  • 將數據列寫入檔案。

  • 透過網路將數據列傳送至另一個應用程式。

  • 等候一段時間或等待用戶輸入。

解析度: 若要解決此問題,請使用緊密 WHILE/FOR 迴圈,盡可能快速地擷取所有結果。 這表示將結果儲存在記憶體中,然後才執行更多處理。

用戶端應用程式電腦 (I/O、記憶體或 CPU)

即使開發應用程式程式代碼以儘快擷取結果,系統資源問題仍可能導致整個用戶端程式變慢。 例如:

如果執行用戶端應用程式的電腦具有資源條件約束,應用程式可能不會快速擷取結果。 例如:

  • 100% CPU 使用率

  • 記憶體不足 (取用所有記憶體)

  • 緩慢的 I/O (應用程式可能會寫入結果或記錄)

這些資源條件約束可能會導致傳入結果的處理速度變慢,並導致 SQL Server 遇到等候類型 ASYNC_NETWORK_IO

解析度:若要解決此問題,請使用 效能監視器 之類的工具來診斷執行應用程式的系統,然後消除任何資源條件約束。 下列其中一種方法可能適用於您:

  • 停止其他應用程式執行。

  • 修正這些應用程式中的任何程式碼問題。

  • 如果應用程式已完全調整,請升級系統上的硬體。

NIC/網路

網路或網路適配器 (NIC) 可能會造成網路流量延遲,並自然延遲擷取結果並與 SQL Server 通訊。 網路延遲通常是由下列問題所造成:

  • 網路適配器驅動程序問題

  • 網路篩選驅動程序問題

  • 設定錯誤或防火牆錯誤

  • 路由器問題

  • 因為流量 (較不常見的多載網路)

解析度: 若要診斷這些問題,您可以 收集網路追蹤 ,並尋找封包重設和重新傳輸。 然後,您可以解決網路相關問題,以消除封包重設/重新傳輸。

另請參閱

sys.dm_os_wait_stats中的ASYNC_NETWORK_IO