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.
- In .NET Framework System.Data.SqlClient wordt de time-outwaarde ingesteld op de eigenschap CommandTimeout.
- In de ODBC-API wordt deze ingesteld via het
SQL_ATTR_QUERY_TIMEOUT
kenmerk in de functie SQLSetStmtAttr . - In de JDBC-API (Java Database Connectivity) wordt deze ingesteld via de methode setQueryTimeout.
- In OLEDB wordt deze ingesteld via de
DBPROP_COMMANDTIMEOUT
eigenschap in deDBPROP
structuur. - In VBA (Excel) wordt deze ingesteld via de eigenschap ADODB.Command.CommandTimeout.
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:
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
enrpc_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 Voer de query's uit en test deze in SQLCMD of in SQL Server Management Studio (SSMS).
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.
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 deoptions_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.
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.