Behandeln von Problemen mit dem Abfragetimeout
Problembeschreibung
Angenommen, eine Anwendung fragt Daten aus einer SQL Server-Datenbank ab. Wenn die Abfrage keine Daten innerhalb des konfigurierten Timeoutwerts zurückgibt (in der Regel 30 Sekunden), bricht die Anwendung die Abfrage ab und generiert eine der folgenden Fehlermeldungen:
-
Timeout ist abgelaufen. Das Timeout ist vor dem Beenden des Vorgangs eingetreten, oder der Server reagiert nicht. Die Anweisung wurde beendet.
-
System.Data.SqlClient.SqlException: Timeout abgelaufen. Das Timeout ist vor dem Beenden des Vorgangs eingetreten, oder der Server reagiert nicht.
Erklärung
Diese Fehler treten auf der Anwendungsseite auf. Die Anwendung legt einen Timeoutwert fest, und wenn das Timeout erreicht ist, wird die Abfrage abgebrochen. Auf der SQL Server-Seite verursacht ein Abfrageabbruch von der Clientseite ein Aufmerksamkeitsereignis, Fehler 3617 (MSSQLSERVER_3617). Wenn der Timeoutwert auf der Anwendungsseite auf 0 festgelegt ist (kein Zeitlimit), führt die Datenbank-Engine die Abfrage aus, bis sie abgeschlossen ist.
- In .NET Framework System.Data.SqlClient wird der Timeoutwert für die CommandTimeout-Eigenschaft festgelegt.
- In der ODBC-API wird sie über das
SQL_ATTR_QUERY_TIMEOUT
Attribut in der SQLSetStmtAttr-Funktion festgelegt. - In Java Database Connectivity-API (JDBC) wird sie über die setQueryTimeout-Methode festgelegt.
- In OLEDB wird es durch die Eigenschaft auf der
DBPROP_COMMANDTIMEOUT
DBPROP
Struktur gesetzt. - In VBA (Excel) wird sie über die ADODB.Command.CommandTimeout-Eigenschaft festgelegt.
Abfragetimeout unterscheidet sich von einer Verbindungstimeouteigenschaft. Letzteres steuert, wie lange auf eine erfolgreiche Verbindung gewartet wird und nicht an der Abfrageausführung beteiligt ist. Weitere Informationen finden Sie unter Abfragetimeout nicht mit dem Verbindungstimeout.
Schritte zur Problembehandlung
Der häufigste Grund für Abfragetimeouts ist bisher eine unterschreibende Abfrageabfrage. Dies bedeutet, dass die Abfrage länger als der vordefinierte Abfragetimeoutwert ausgeführt wird. Eine schnellere Ausführung der Abfrage ist das empfohlene erste Ziel ihrer Problembehandlung. So überprüfen Sie Abfragen:
Verwenden Sie erweiterte Ereignisse oder SQL-Ablaufverfolgung , um die Abfragen zu identifizieren, die zu Timeoutfehlern führen. Sie können das Aufmerksamkeitsereignis zusammen mit den und
rpc_completed
densql_batch_completed
erweiterten Ereignissen nachverfolgen und mit demselbensession_id
korrelieren. Wenn Sie feststellen, dass ein abgeschlossenes Ereignis unmittelbar auf ein Aufmerksamkeitsereignis folgt und die Dauer des abgeschlossenen Ereignisses ungefähr der Timeouteinstellung entspricht, haben Sie die Abfrage identifiziert. Hier sehen Sie ein Beispiel:Notiz
Im Beispiel wurde die
SELECT
Abfrage fast genau 30 Sekunden lang ausgeführt und beendet. Das Aufmerksamkeitsereignis mit derselben Sitzungs-ID gibt an, dass die Abfrage von der Anwendung abgebrochen wurde.Name Session_id Sql_text Dauer (Mikrosekunden) Timestamp sql_batch_started 54 Wählen Sie die Auslassungspunkte (...) aus. von Kunden WHERE cid = 192937 NULL 2021-09-30 09:50:25.0000 sql_batch_completed 54 Wählen Sie die Auslassungspunkte (...) aus. von Kunden WHERE cid = 192937 29999981 2021-09-30 09:50:55.0000 Aufmerksamkeit 54 Wählen Sie die Auslassungspunkte (...) aus. von Kunden WHERE cid = 192937 40.000 2021-09-30 09:50:55.0400 Führen Sie die Abfragen in SQLCMD oder sql Server Management Studio (SSMS) aus, und testen Sie sie.
Wenn die Abfragen auch in SQLCMD und SSMS langsam sind, beheben Und verbessern Sie die Leistung der Abfragen. Ausführliche Informationen finden Sie unter Problembehandlung für langsam ausgeführte Abfragen in SQL Server.
Notiz
In SQLCMD und SSMS ist der Timeoutwert auf 0 (kein Zeitlimit) festgelegt, und die Abfragen können getestet und untersucht werden.
Wenn die Abfragen in SQLCMD und SSMS schnell sind, aber langsam auf der Anwendungsseite sind, ändern Sie die Abfragen so, dass dieselben SET-Optionen verwendet werden, die in SQLCMD und SSMS verwendet werden. Vergleichen Sie die SET-Optionen, indem Sie eine Erweiterte Ereignisablaufverfolgung (Anmelde- und Verbindungsereignisse mit
collect_options_text
) sammeln und dieoptions_text
Spalte überprüfen. Ein Beispiel: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))
Weitere Informationen finden Sie unter Problembehandlung bei der Abfrageleistung zwischen Datenbankanwendung und SSMS.
Überprüfen Sie, ob die
CommandTimeout
Einstellung kleiner als die erwartete Abfragedauer ist. Wenn die Einstellung des Benutzers korrekt ist und timeouts noch auftreten, liegt es an einem Abfrageleistungsproblem. Hier ist ein ADO.NET Codebeispiel mit einem Timeoutwert, der auf 10 Sekunden festgelegt ist: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); } } } } }
Abfragetimeout ist nicht mit dem Verbindungstimeout identisch
Ein Abfragetimeout unterscheidet sich von einem Verbindungstimeout oder einem Anmeldetimeout. Das Verbindungs- oder Anmeldetimeout tritt auf, wenn die anfängliche Verbindung mit dem Datenbankserver einen vordefinierten Timeoutzeitraum erreicht. Zu diesem Zeitpunkt wurde keine Abfrage an den Server übermittelt. Diese Meldungen sind Beispiele für Verbindungs- oder Anmeldetimeoutfehler:
-
Verbindungstimeoutfehler. Das Zeitlimit ist während des Versuchs verstrichen, die Handshakebestätigung vor der Anmeldung zu verarbeiten. Dies kann daran liegen, dass beim Handshake vor der Anmeldung ein Fehler aufgetreten ist oder der Server nicht rechtzeitig reagieren konnte. Die Dauer des Verbindungsversuchs zu diesem Server war [Pre-Login] initialization=23; handshake=14979;
-
Timeout ist abgelaufen. Das Timeout ist vor dem Beenden des Vorgangs eingetreten, oder der Server reagiert nicht. System.ComponentModel.Win32Exception (0x80004005): Die Warteoperation wurde abgebrochen.
Der Timeoutwert für die Verbindung ist eine clientseitige Einstellung und wird in der Regel auf 15 Sekunden festgelegt. Weitere Informationen zur Problembehandlung bei Verbindungstimeouts finden Sie unter Problembehandlung bei Verbindungstimeouts. Informationen zur Problembehandlung bei Abfragetimeouts finden Sie in diesem Video.