Share 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 verlopen. De time-outperiode is verstreken voordat de bewerking is voltooid of de server reageert niet. De instructie is beëindigd.

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

Uitleg

Deze fouten treden op aan de toepassingskant. De toepassing stelt een time-outwaarde in en als de time-out is bereikt, wordt de query geannuleerd. Aan de kant van SQL Server veroorzaakt een annulering van de query van de clientzijde een focusgebeurtenis, 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.

  • In .NET Framework System.Data.SqlClient wordt de time-outwaarde ingesteld voor de eigenschap CommandTimeout.
  • In ODBC API wordt dit ingesteld via het kenmerk SQL_ATTR_QUERY_TIMEOUT in de functie SQLSetStmtAttr.
  • In Java Database Connectivity (JDBC) API wordt dit ingesteld via de methode setQueryTimeout.
  • In OLEDB wordt het ingesteld via de eigenschap DBPROP_COMMANDTIMEOUT in de structuur DBPROP.
  • In VBA (Excel) wordt dit ingesteld via de eigenschap ADODB.Command.CommandTimeout.

Time-out voor query's verschilt van een eigenschap voor time-out voor verbindingen. De laatste bepaalt hoe lang moet worden gewacht op een succesvolle verbinding en is niet betrokken bij het uitvoeren van query's. Raadpleeg Time-out voor query's is niet hetzelfde als time-out voor verbinding voor meer informatie.

Stappen voor probleemoplossing

Veruit de meest voorkomende reden voor time-outs voor query's zijn ondermaatse query's. Dit betekent dat de query langer wordt uitgevoerd dan de vooraf gedefinieerde time-outwaarde voor query's. Het sneller laten verlopen van de query is het aanbevolen eerste doel van uw probleemoplossing. Ga als volgt te werk om query's te controleren:

  1. Gebruik Uitgebreide gebeurtenissen of SQL Trace om de query's te identificeren die de time-outfouten veroorzaken. U kunt de focusgebeurtenis samen met de uitgebreide gebeurtenissen sql_batch_completed en rpc_completed traceren en ze op dezelfde session_id correleren. Als u ziet dat een voltooide gebeurtenis onmiddellijk 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:

    Opmerking

    In het voorbeeld liep de SELECT-query bijna exact 30 seconden en stopte. De focusgebeurtenis met dezelfde sessie-ID geeft aan dat de query door de toepassing is geannuleerd.

    Naam Session_id Sql_text Duur (microseconden) Tijdstempel
    sql_batch_started 54 Selecteer … van klanten WAAR cid = 192937 NULL 30-09-2021 09:50:25.0000
    sql_batch_completed 54 Selecteer … van klanten WAAR cid = 192937 29999981 30-09-2021 09:50:55.0000
    Let op 54 Selecteer … van klanten WAAR cid = 192937 40000 30-09-2021 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 problemen oplossen en de prestaties van de query's verbeteren. Zie Problemen met trage query's in SQL Server oplossen voor gedetailleerde informatie

    Opmerking

    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 langzaam aan de toepassingszijde, wijzigt u de query's zodat ze dezelfde SET-opties gebruiken die worden gebruikt in SQLCMD en SSMS. Vergelijk de SET-opties door een Uitgebreide gebeurtenissentracering te verzamelen (login en verbindingsgebeurtenissen met collect_options_text) en controleer de kolom options_text. 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))
    

    Voor meer informatie, raadpleeg Verschillen in queryprestaties tussen databasetoepassing en SSMS oplossen.

  5. Controleer of de instelling CommandTimeout kleiner is dan de verwachte duur van de query. Als de gebruikersinstelling correct is en er nog steeds time-outs optreden, komt dit door een probleem met de queryprestaties. Hier is een voorbeeld van een ADO.NET-code 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 voor query's is niet hetzelfde als time-out voor verbinding

Een time-out voor een query verschilt van een time-out voor een verbinding of een time-out voor inloggen. De verbindings- of aanmeldingstime-out treedt op wanneer de eerste 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 verbindings- of aanmeldingstime-outfout:

  • Verbindingstime-out verlopen. De time-outperiode is verstreken tijdens het gebruik van de handshake-bevestiging voorafgaand aan de aanmelding. Dit kan zijn omdat de handshake voorafgaand aan het aanmelden is mislukt of de server niet op tijd kon reageren. De duur van de poging om verbinding te maken met deze server was [Pre-Login] initialization=23; handshake=14979;

  • Time-out is verlopen. De time-outperiode is verstreken voordat de bewerking is 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. Voor meer informatie over het oplossen van verbindingstime-out, raadpleeg oplossen van verbindingstime-outs. Bekijk deze video voor het oplossen van problemen met querytime-outs.