Sorgu zaman aşımı hatalarını giderme

Belirtiler

Bir uygulamanın, SQL Server veritabanından sorgu yaptığını varsayalım. Sorgu, yapılandırılan zaman aşımı değeri (genellikle 30 saniye) içinde veri döndürmezse uygulama sorguyu iptal eder ve şu hata iletilerinden birini oluşturur:

  • Zaman aşımı süresi doldu. İşlem tamamlanmadan önce zaman aşımı süresi geçti veya sunucu yanıt vermiyor Deyim sonlandırıldı.

  • System.Data.SqlClient.SqlException: Zaman aşımı süresi doldu. İşlem tamamlanmadan önce zaman aşımı süresi geçti veya sunucu yanıt vermiyor.

Açıklama

Bu hatalar uygulama tarafında oluşur. Uygulama bir zaman aşımı değeri ayarlar ve zaman aşımına ulaşılırsa sorguyu iptal eder. SQL Server tarafında, istemci tarafından bir sorgu iptali Dikkat olayına neden olur, hata 3617 (MSSQLSERVER_3617). Uygulama tarafındaki zaman aşımı değeri 0 olarak ayarlanmışsa (zaman sınırı yoksa), Veritabanı Altyapısı tamamlanana kadar sorguyu yürütür.

  • .NET Framework System.Data.SqlClient'da, zaman aşımı değeri CommandTimeout özelliğinde ayarlanır.
  • ODBC API'sinde, SQLSetStmtAttr işlevindeki SQL_ATTR_QUERY_TIMEOUT özniteliği aracılığıyla ayarlanır.
  • Java Veritabanı Bağlantısı (JDBC) API'sinde, setQueryTimeout yöntemiyle ayarlanır.
  • OLEDB'de, DBPROP yapısındaki DBPROP_COMMANDTIMEOUT özelliği aracılığıyla ayarlanır.
  • VBA'da (Excel), ADODB.Command.CommandTimeout özelliği aracılığıyla ayarlanır.

Sorgu zaman aşımı, bağlantı zaman aşımı özelliğinden farklıdır. İkinci seçenek, başarılı bir bağlantının ne kadar süreyle beklenip beklenmeyeceğini denetler ve sorgu yürütmeyle alakalı değildir. Daha fazla bilgi için bkz. Sorgu zaman aşımı, bağlantı zaman aşımı ile aynı değildir.

Sorun giderme adımları

Şimdiye kadar sorgu zaman aşımlarının en yaygın nedeni, düşük performanslı sorgulardır. Bu, sorgunun önceden tanımlanmış sorgu zaman aşımı değerinden daha uzun çalıştığı anlamına gelir. Sorgunun daha hızlı çalışmasını sağlama, sorun giderme işleminizin önerilen ilk hedefidir. Sorgular şu şekilde kontrol edilir:

  1. Zaman aşımı hatalarına neden olan sorguları belirlemek için Genişletilmiş Olaylar veya SQL İzleme'yi kullanın. dikkat olayını, sql_batch_completed ve rpc_completed genişletilmiş olaylarıyla birlikte izleyebilir ve bunları aynı session_id üzerinde ilişkilendirebilirsiniz. Tamamlanan bir olayın hemen ardından bir dikkat olayı geldiğini ve tamamlanan olayın süresinin yaklaşık olarak zaman aşımı ayarına karşılık geldiğini gözlemlerseniz sorguyu tanımlamış olursunuz. İşte bir örnek:

    Not

    Örnekte, SELECT sorgusu neredeyse tam 30 saniye boyunca çalışıp durdu. Aynı oturum kimliğine sahip dikkat olayı, sorgunun uygulama tarafından iptal edildiğine işaret eder.

    Name Session_id Sql_text Süre (mikrosaniye) Zaman damgası
    sql_batch_started 54 … seçin. Müşterilerden WHERE cid = 192937 NULL 30.09.2021 09:50:25.0000
    sql_batch_completed 54 … seçin. Müşterilerden WHERE cid = 192937 29999981 30.09.2021 09:50:55.0000
    Dikkat 54 … seçin. Müşterilerden WHERE cid = 192937 40000 30.09.2021 09:50:55.0400
  2. Sorguları SQLCMD veya SQL Server Management Studio'da (SSMS) yürütün ve test edin.

  3. SQLCMD ve SSMS'de sorgular da yavaşsa, sorguların performans sorunlarını giderin ve performansını geliştirin. Ayrıntılı bilgi için bkz. SQL Server'da yavaş çalışan sorgularda sorun giderme

    Not

    SQLCMD ve SSMS'de zaman aşımı değeri 0 olarak ayarlanmış (zaman sınırı yoktur) olup sorgular test edilebilir ve araştırılabilir.

  4. Sorgular SQLCMD ve SSMS'de hızlı, ancak uygulama tarafında yavaşsa, sorguları SQLCMD ve SSMS'de kullanılan aynı AYARLANMIŞ seçenekleri kullanacak şekilde değiştirin. Genişletilmiş Olaylar izlemesi (oturum açma ve olayları collect_options_text ile bağlama) toplayarak AYARLANMIŞ seçenekleri karşılaştırın ve options_text sütununu denetleyin. İşte bir örnek:

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

    Daha fazla bilgi için bkz. Veritabanı uygulaması ile SSMS arasındaki sorgu performansı farkı sorununu giderme.

  5. CommandTimeout ayarının beklenen sorgu süresinden küçük olup olmadığını denetleyin. Kullanıcının ayarı doğruysa ve yine de zaman aşımları oluşuyorsa, bunun nedeni bir sorgu performansı sorunudur. Zaman aşımı değeri 10 saniye olarak ayarlanmış bir ADO.NET kod örneği şu şekildedir:

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

Sorgu zaman aşımı, bağlantı zaman aşımı ile aynı değildir

Sorgu zaman aşımı, bağlantı zaman aşımı veya oturum açma zaman aşımından farklıdır. Bağlantı veya oturum açma zaman aşımı, veritabanı sunucusuna ilk bağlantı önceden tanımlanmış bir zaman aşımı süresine ulaştığında oluşur. Bu aşamada, sunucuya hiçbir sorgu gönderilmemiştir. Bu iletiler bağlantı veya oturum açma zaman aşımı hatası örnekleridir:

  • Bağlantı Zaman Aşımı Süresi Doldu. Oturum açma öncesi el sıkışması bildirimini kullanmaya çalışırken zaman aşımı süresi doldu. Bunun nedeni, oturum açma öncesi el sıkışmasının başarısız olmuş veya sunucunun zamanında geri yanıt verememiş olması olabilir. Bu sunucuya bağlanmaya çalışırken harcanan süre [Oturum Açma Öncesi] başlatma=23 idi; el sıkışma=14979;

  • Zaman aşımı süresi doldu. İşlem tamamlanmadan önce zaman aşımı süresi geçti veya sunucu yanıt vermiyor. System.ComponentModel.Win32Exception (0x80004005): Bekleme işlemi zaman aşımına uğradı.

Bağlantı zaman aşımı değeri istemci tarafına ait bir ayardır ve genellikle 15 saniye olarak ayarlanır. Bağlantı zaman aşımı sorunlarını giderme hakkında daha fazla bilgi için bkz. bağlantı zaman aşımı sorunlarını giderme. Sorgu zaman aşımı sorunlarını gidermek için bu video'yu izleyin.