Behandeln von Abfragetimeoutfehlern

Zusammenfassung

Ein Abfragetimeoutfehler in SQL Server tritt auf, wenn eine Abfrage keine Daten zurückgibt, bevor das Befehlstimeout der Clientanwendung abläuft. Die Clientanwendung bricht dann die Abfrage ab und meldet "Timeout abgelaufen". In diesem Artikel wird erläutert, wie Sie bestätigen, dass ein Abfragetimeout (kein Verbindungstimeout) aufgetreten ist, wie Sie die spezifische Abfrage identifizieren, indem Sie das attention Ereignis mit sql_batch_completed und rpc_completed erweiterten Ereignissen korrelieren und wie Sie das Befehlstimeout in ADO festlegen.NET, ODBC, REPORTS, OLE DB und ADO festlegen. Die häufigste Ursache ist eine langsame Abfrage, daher ist die empfohlene Korrektur die Optimierung der Abfrage, anstatt nur den Timeoutwert auszulösen. Verwenden Sie diesen Artikel, wenn eine Anwendung Timeoutfehler meldet, während SQL Server Aufmerksamkeitsereignisse (Fehler 3617) mit einer Dauer aufzeichnet, die eng mit dem konfigurierten Timeout übereinstimmt.

Symptome eines Abfragetimeoutfehlers

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.

Warum Abfragetimeoutfehler auftreten

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, unabhängig davon, wie lange dies ist, Millisekunden oder Tage.

Der Timeoutwert wird für jeden Datenzugriffstreiber oder jede API unterschiedlich 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 zum Identifizieren und Auflösen der Abfrage, die zu einem Zeitüberschreitung führt

Der häufigste Grund für Abfragetimeouts ist das Unterschreiten von Abfragen. Dies bedeutet, dass die Abfrage länger als der vordefinierte Abfragetimeoutwert ausgeführt wird. Beschleunigen Sie die Ausführung der Abfrage, um dieses Problem zu beheben. So überprüfen Sie Abfragen:

  1. Verwenden Sie erweiterte Ereignisse oder SQL-Ablaufverfolgung , um die Abfragen zu identifizieren, die die Timeoutfehler verursachen. Sie können das Aufmerksamkeitsereignis zusammen mit den und sql_batch_completed den rpc_completed erweiterten Ereignissen nachverfolgen und mit demselben session_idkorrelieren. 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 wird die SELECT Abfrage fast genau 30 Sekunden lang ausgeführt und beendet. Das Aufmerksamkeitsereignis mit derselben Sitzungs-ID gibt an, dass die Anwendung die Abfrage abgebrochen hat.

    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
  2. Führen Sie die Abfragen in sqlcmd oder in SQL Server Management Studio (SSMS) aus, und testen Sie sie.

  3. 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 wird der Timeoutwert auf 0 (kein Zeitlimit) festgelegt, und Sie können die Abfragen testen und untersuchen.

  4. Wenn die Abfragen in sqlcmd und SSMS schnell sind, aber langsam auf der Anwendungsseite, ä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 die options_text Spalte überprüfen. Hier sehen Sie 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.

  5. Überprüfen Sie, ob die CommandTimeout Einstellung kleiner als die erwartete Abfragedauer ist. Wenn die Einstellung des Benutzers korrekt ist und timeouts weiterhin 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);
                    }
                }
            }
        }
    }
    

Das 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. An diesem Punkt hat der Client keine Abfrage an den Server gesendet. Diese Meldungen sind Beispiele für Verbindungstimeout- 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 von Verbindungstimeouts finden Sie unter Problembehandlung bei Verbindungstimeoutfehlern.