Delen via


Time-outfouten bij query's oplossen

Symptomen

Stel dat een toepassing gegevens opvraagt uit een SQL Server-database. Als de query geen gegevens retourneert binnen de geconfigureerde time-outwaarde (meestal 30 seconden), annuleert de toepassing de query en genereert een van deze foutberichten:

  • Time-out is verstreken. De time-outperiode is verstreken voordat de bewerking werd voltooid, of de server reageert niet. De instructie is beëindigd.

  • System.Data.SqlClient.SqlException: Time-out verstreken. De time-outperiode is verstreken voordat de bewerking werd voltooid, of de server reageert niet.

Uitleg

Deze fouten treden op aan de toepassingszijde. De toepassing stelt een time-outwaarde in en als de time-out is bereikt, wordt de query geannuleerd. Aan de zijde van SQL Server veroorzaakt een queryannulering aan de clientzijde een gebeurtenis Aandacht, fout 3617 (MSSQLSERVER_3617). Als de time-outwaarde aan de toepassingszijde is ingesteld op 0 (geen tijdslimiet), voert de database-engine de query uit totdat deze is voltooid.

Time-out van query's verschilt van een time-outeigenschap voor verbinding. Deze laatste bepaalt hoe lang moet worden gewacht op een geslaagde verbinding en niet betrokken is bij het uitvoeren van query's. Zie Time-out van query's is niet hetzelfde als time-out voor verbindingen.

Stappen voor probleemoplossing

Veruit de meest voorkomende reden voor time-outs van query's is het onderbewerken van query's. Dit betekent dat de query langer wordt uitgevoerd dan de vooraf gedefinieerde time-outwaarde voor query's. Het is het aanbevolen eerste doel van uw probleemoplossing om de query sneller uit te voeren. U kunt als volgt query's controleren:

  1. Gebruik Uitgebreide gebeurtenissen of SQL Trace om de query's te identificeren die de time-outfouten veroorzaken. U kunt de aandachtsevenement samen met de sql_batch_completed en rpc_completed uitgebreide gebeurtenissen traceren en deze correleren op hetzelfdesession_id. Als u merkt dat een voltooide gebeurtenis direct wordt gevolgd door een aandachtsgebeurtenis en de duur van de voltooide gebeurtenis ongeveer overeenkomt met de time-outinstelling, hebt u de query geïdentificeerd. Hier volgt een voorbeeld:

    Notitie

    In het voorbeeld is de SELECT query bijna 30 seconden uitgevoerd en gestopt. De aandachtsgebeurtenis met dezelfde sessie-id geeft aan dat de query is geannuleerd door de toepassing.

    Naam Session_id Sql_text Duur (microseconden) Tijdstempel
    sql_batch_started 54 Selecteer … from Customers WHERE cid = 192937 NULL 2021-09-30 09:50:25.0000
    sql_batch_completed 54 Selecteer … from Customers WHERE cid = 192937 29999981 2021-09-30 09:50:55.0000
    Opmerking 54 Selecteer … from Customers WHERE cid = 192937 40.000 2021-09-30 09:50:55.0400
  2. Voer de query's uit en test deze in SQLCMD of in SQL Server Management Studio (SSMS).

  3. Als de query's ook traag zijn in SQLCMD en SSMS, kunt u de prestaties van de query's oplossen en verbeteren. Zie Problemen met trage query's in SQL Server oplossen voor gedetailleerde informatie

    Notitie

    In SQLCMD en SSMS is de time-outwaarde ingesteld op 0 (geen tijdslimiet) en kunnen de query's worden getest en onderzocht.

  4. Als de query's snel zijn in SQLCMD en SSMS, maar traag aan de toepassingszijde, wijzigt u de query's zodat dezelfde SET-opties worden gebruikt die worden gebruikt in SQLCMD en SSMS. Vergelijk de SET-opties door een tracering voor uitgebreide gebeurtenissen te verzamelen (aanmelden en gebeurtenissen te verbinden met collect_options_text) en de options_text kolom te controleren. Hier volgt een voorbeeld:

    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))
    

    Zie Problemen met queryprestaties tussen databasetoepassing en SSMS oplossen voor meer informatie.

  5. Controleer of de CommandTimeout instelling kleiner is dan de verwachte queryduur. Als de instelling van de gebruiker juist is en er nog steeds time-outs optreden, is dit het gevolg van een prestatieprobleem met query's. Hier volgt een ADO.NET codevoorbeeld met een time-outwaarde ingesteld op 10 seconden:

    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);
                    }
                }
            }
        }
    }
    

Time-out van query is niet hetzelfde als time-out voor verbinding

Een time-out voor query's verschilt van een time-out voor een verbinding of een time-out voor aanmelding. De time-out voor de verbinding of aanmelding vindt plaats wanneer de initiële verbinding met de databaseserver een vooraf gedefinieerde time-outperiode bereikt. In deze fase is er geen query verzonden naar de server. Deze berichten zijn voorbeelden van een time-outfout voor verbinding of aanmelding:

  • Verbindingstime-out is verstreken. De time-outperiode is verstreken tijdens het gebruik van de bevestiging van de handshake vóór aanmelding. Dit kan komen doordat de handshake vóór aanmelding is mislukt of omdat de server niet op tijd kon reageren. De tijd die werd doorgebracht met het proberen verbinding te maken met deze server was - [Pre-Login] initialization=23; handshake=14979;

  • Time-out is verstreken. De time-outperiode is verstreken voordat de bewerking werd voltooid, of de server reageert niet. System.ComponentModel.Win32Exception (0x80004005): Er is een time-out opgetreden voor de wachtbewerking.

De time-outwaarde voor de verbinding is een instelling aan de clientzijde en is doorgaans ingesteld op 15 seconden. Zie verbindingstime-out oplossen voor meer informatie over het oplossen van problemen met time-outs voor verbindingen. Bekijk deze video voor het oplossen van problemen met time-outs voor query's.