Microsoft.Data.SqlClient.SqlException (0x80131904): 执行超时已过期。操作完成之前超时时间已到或服务器无响应。语句已终止。
Microsoft.Data.SqlClient.SqlException (0x80131904): Execution Timeout Expired. The timeout period elapsed prior to completion of the operation or the server is not responding. The statement has been terminated.
ID: dotnet/ef-core-sql-timeout-large-data
版本兼容性
| 版本 | 状态 | 引入 | 弃用 | 备注 |
|---|---|---|---|---|
| 6.0 | active | — | — | — |
| 7.0 | active | — | — | — |
| 8.0 | active | — | — | — |
| 9.0 | active | — | — | — |
根因分析
SQL 查询执行超过配置的命令超时时间,通常由大数据量、缺少索引或 Entity Framework Core 生成的低效 LINQ 查询引起。
English
SQL query execution exceeds the configured command timeout, typically due to large data volumes, missing indexes, or inefficient LINQ queries generated by Entity Framework Core.
官方文档
https://learn.microsoft.com/en-us/sql/relational-databases/errors-events/mssqlserver-2-database-engine-error解决方案
-
通过早期添加 .Where() 过滤器和使用 .Select() 投影仅需要的列来优化 LINQ 查询。示例:var data = context.Orders.Where(o => o.Date > DateTime.UtcNow.AddDays(-30)).Select(o => new { o.Id, o.Total }).ToList(); -
在 WHERE、JOIN 和 ORDER BY 子句中使用的列上添加数据库索引。使用 SQL Server Management Studio 或 EF Core 迁移:CREATE INDEX IX_Orders_Date ON Orders (Date);
-
临时增加特定操作的 CommandTimeout:context.Database.SetCommandTimeout(120); 或在连接字符串中:"Command Timeout=120;"
无效尝试
常见但无效的做法:
-
Increasing CommandTimeout to a very high value (e.g., 300 seconds) without optimizing the query
70% 失败
Temporary fix that masks the underlying performance issue; query may still time out under heavy load or with larger datasets.
-
Adding .AsNoTracking() to all queries without understanding if tracking is needed
50% 失败
AsNoTracking improves performance for read-only queries but does not fix inefficient joins or missing indexes.
-
Splitting the query into multiple smaller queries without using .Include() properly
65% 失败
Multiple round trips can increase total execution time and cause N+1 query problems, worsening performance.