2025年12月29日 星期一

[研究]SSMS中TSQL執行很快,ASP.NET WebForm 的 SqlDataSource + GridView 很慢

[研究]SSMS中TSQL執行很快,ASP.NET WebForm 的 SqlDataSource + GridView 很慢

2025-12-29

環境:Visual Studio 2022 + ASP.NET + WebForm + Web Application + C# + SQL Server 2019 + SQL Server Management Studio (SSMS) 20.2

********************************************************************************

在 SSMS 中 TSQL 執行很快,但拿去 ASP.NET WebForm 的 SqlDataSource + GridView 很慢,甚至出現下面問題: 

System.ComponentModel.Win32Exception: 等候操作已逾時。

 System.Data.SqlClient.SqlException (0x80131904): 執行逾時到期。 

增加 CommandTimeout 可解決,可能原因 ? 若不改 CommandTimeout ,有其他解法 ?

********************************************************************************

ChatGPT (敝人精簡過)

1️⃣ 可能原因

網路延遲

資料傳輸量大

GridView 的 RowDataBound 事件做大量運算也會慢。

SqlDataSource 的 CommandTimeout 預設 30 秒,一旦資料量大或查詢複雜就容易逾時。

鎖定或阻塞

如果 ASP.NET 同時有其他交易或查詢,可能被鎖住導致逾時。

SSMS 常用的是 單用戶、未鎖定表,所以很快。

2️⃣ 不改 CommandTimeout 的解法

(A) 優化查詢

  • 確保 T-SQL 已經 加索引,避免全表掃描。
  • 避免 SELECT *,只選必要欄位。
  • 使用 分頁查詢(OFFSET-FETCH 或 ROW_NUMBER())。

範例:

SELECT *
FROM (
    SELECT ROW_NUMBER() OVER (ORDER BY Id) AS RowNum, *
    FROM MyTable
) AS T
WHERE T.RowNum BETWEEN 1 AND 50

配合 GridView 分頁,每次只抓一頁資料。

(B) GridView 頁面化

  • 啟用 GridView 的 AllowPaging="true",讓 SqlDataSource 只抓分頁資料。
  • 避免一次拉回整個資料表。

(C) 使用自訂資料來源

  • 不用 SqlDataSource,改用 ObjectDataSource 或自己寫 DataAccess 層,用 SqlDataReader 或 DataTable。
  • 可以針對每頁做分頁 SQL 查詢,減少一次取回資料量。

(D) 檢查網路及伺服器效能

  • 確認 Web Server 與 DB Server 網路延遲低。
  • 避免一次傳回大資料量。
  • 可以使用 SqlDataReader 逐行讀取而不是 DataSet/DataTable。

(E) 確認 SQL Server SET 選項

某些執行計畫差異問題可以透過調整 SET ARITHABORT ON/OFF 修正。

SET ARITHABORT ON;
SELECT ...

可以在 SqlDataSource 的 SelectCommand 前執行。

3️⃣ 結論建議

  • 如果資料量很大或計算複雜,增加 CommandTimeout 是解法之一。
  • 更好的做法是:
    • 分頁查詢 + GridView 分頁
    • 只抓必要欄位
    • 優化索引
    • 減少 GridView 運算量
  • 這樣不但不用增加 Timeout,使用者體驗也會好很多。

重點

SqlDataSource + GridView 慢,很多時候不是 SQL 本身慢,而是 整個資料拉回與前端渲染流程慢。真正解法是 分頁、只抓必要資料、減少 GridView 運算量,而非單純拉長 Timeout

(完)

相關

沒有留言:

張貼留言