这些错误发生在应用程序端。 应用程序设置超时值,如果超时将取消查询。 在 SQL Server 端,客户端的查询取消会导致注意事件,错误 3617 (
MSSQLSERVER_3617)
。 如果应用程序端的超时值设置为
0
(没有时间限制),则数据库引擎将执行查询,直到查询完成。
在 .NET Framework
System.Data.SqlClient
中,超时值在
CommandTimeout
属性上设置。
在 ODBC API 中,它通过
SQLSetStmtAttr
函数中的
SQL_ATTR_QUERY_TIMEOUT
属性进行设置。
在 Java 数据库连接 (JDBC) API 中,它通过
setQueryTimeout
方法进行设置。
在 OLEDB 中,它通过
DBPROP
结构上的
DBPROP_COMMANDTIMEOUT
属性进行设置。
在 VBA (Excel) 中,它通过
ADODB.Command.CommandTimeout
属性进行设置。
查询超时与连接超时属性不同。 后者控制等待成功连接的时间,而不参与查询执行。 有关详细信息,请参阅
查询超时与连接超时不同
。
故障排除步骤
到目前为止,查询超时的最常见原因是查询表现不佳。 这意味着查询的运行时间比预定义的查询超时值长。 提高查询的运行速度是推荐排查的首要目标。 以下是检查查询的方法:
使用“扩展事件”
或“SQL 跟踪”
来识别导致超时错误的查询。 可以将
关注
事件与
sql_batch_completed
事件和
rpc_completed
扩展事件一起跟踪,并将其关联在同一个
session_id
上。 如果观察到完成的事件紧接着关注事件,并且完成事件的持续时间与超时设置相对应,则已确定查询。 下面是一个示例:
在该示例中,
SELECT
查询几乎正好运行了 30 秒然后停止。 具有相同会话 ID 的注意事件表示应用程序已取消查询。
在 SQLCMD 或 SQL Server Management Studio (SSMS) 中执行和测试查询。
如果 SQLCMD 和 SSMS 中的查询速度也较慢,请对查询进行疑难解答并提高性能。
在 SQLCMD 和 SSMS 中,超时值设置为
0
(无时间限制)并且可以测试和调查查询。
如果在 SQLCMD 和 SSMS 中的查询速度很快,但在应用程序端速度缓慢,请更改查询以使用 SQLCMD 和 SSMS 中使用的相同
SET 选项
。 通过收集扩展事件跟踪(使用
collect_options_text
登录和连接事件)比较 SET 选项并查看
options_text
列。 下面是一个示例:
ALTER EVENT SESSION [setOptions] ON SERVER
ADD EVENT sqlserver.existing_connection(SET collect_options_text=(1)
ACTION(package0.event_sequence,package0.last_error,sqlos.system_thread_id,sqlserver.context_info,sqlserver.session_id,sqlserver.sql_text)),
ADD EVENT sqlserver.login(SET collect_options_text=(1)
ACTION(sqlos.system_thread_id,sqlserver.context_info,sqlserver.sql_text))
有关详细信息,请参阅 对数据库应用程序和 SSMS 之间的查询性能差异进行疑难解答。
检查 CommandTimeout
设置是否小于预期的查询持续时间。 如果用户的设置正确但仍然出现超时,则是因为查询性能问题。 下面是一个 ADO.NET 代码示例,超时值设置为 10 秒:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.SqlClient;
using System.Data;
namespace ConsoleApplication6
class Program
static void Main()
string ConnectionString = "Data Source=.\sql2019;Integrated Security=SSPI;Initial Catalog=tempdb;";
string queryString = "exec test";
using (SqlConnection connection = new SqlConnection(ConnectionString))
connection.Open();
SqlCommand command = new SqlCommand(queryString, connection);
// Setting command timeout to 10 seconds
command.CommandTimeout = 10;
//command.ExecuteNonQuery();
try {
command.ExecuteNonQuery();
catch (SqlException e) {
Console.WriteLine("Got expected SqlException due to command timeout ");
Console.WriteLine(e);
查询超时与连接超时不同
查询超时不同于连接超时或登录超时。当与数据库服务器的初始连接达到预定义的超时时间段时,会出现连接或登录超时。 在此阶段,尚未向服务器提交任何查询。 以下是连接或登录超时错误消息的示例:
连接超时时间已到。 在尝试使用登录前握手确认时超过了此超时时间。 这可能是因为登录前握手失败或服务器无法及时响应。 尝试连接到此服务器所花费的持续时间为 [登录前] 初始化 = 23; 握手=14979;