針對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,根據預設,DataSet 和 DataTable 會先擷取所有數據列以完成,用戶端才能存取它。 不過, SqlDataReader 之類的類別可讓應用程式開發人員在從伺服器擷取每個數據列之後,選擇該怎麼做。 應用程式可以一次擷取一個數據列,然後根據商務需求處理此數據列。 例如:
將數據列寫入檔案。
透過網路將數據列傳送至另一個應用程式。
等候一段時間或等待用戶輸入。
解析度: 若要解決此問題,請使用緊密 WHILE/FOR 迴圈,盡可能快速地擷取所有結果。 這表示將結果儲存在記憶體中,然後才執行更多處理。
用戶端應用程式電腦 (I/O、記憶體或 CPU)
即使開發應用程式程式代碼以儘快擷取結果,系統資源問題仍可能導致整個用戶端程式變慢。 例如:
如果執行用戶端應用程式的電腦具有資源條件約束,應用程式可能不會快速擷取結果。 例如:
100% CPU 使用率
記憶體不足 (取用所有記憶體)
緩慢的 I/O (應用程式可能會寫入結果或記錄)
這些資源條件約束可能會導致傳入結果的處理速度變慢,並導致 SQL Server 遇到等候類型 ASYNC_NETWORK_IO
。
解析度:若要解決此問題,請使用 效能監視器 之類的工具來診斷執行應用程式的系統,然後消除任何資源條件約束。 下列其中一種方法可能適用於您:
停止其他應用程式執行。
修正這些應用程式中的任何程式碼問題。
如果應用程式已完全調整,請升級系統上的硬體。
NIC/網路
網路或網路適配器 (NIC) 可能會造成網路流量延遲,並自然延遲擷取結果並與 SQL Server 通訊。 網路延遲通常是由下列問題所造成:
網路適配器驅動程序問題
網路篩選驅動程序問題
設定錯誤或防火牆錯誤
路由器問題
因為流量 (較不常見的多載網路)
解析度: 若要診斷這些問題,您可以 收集網路追蹤 ,並尋找封包重設和重新傳輸。 然後,您可以解決網路相關問題,以消除封包重設/重新傳輸。