Azure SQL Veritabanında kilitlenmeleri analiz etme ve önleme

Şunlar için geçerlidir: Azure SQL Veritabanı

Bu makalede, Azure SQL Veritabanında kilitlenmeleri tanımlama, kilitlenmedeki sorguları tanımlamak için kilitlenme grafiklerini ve Sorgu Deposu'nı kullanma ve kilitlenmelerin yeniden oluşmasını önlemek için değişiklikleri planlama ve test etme öğretildi.

Bu makale kilit çekişmesi nedeniyle oluşan kilitlenmeleri belirlemeye ve analiz etmeye odaklanmaktadır. Kaynaklarda kilitlenmeye neden olabilecek diğer kilitlenme türleri hakkında daha fazla bilgi edinin.

Azure SQL Veritabanında kilitlenmeler nasıl oluşur?

Azure SQL Veritabanındaki her yeni veritabanında varsayılan olarak kaydedilmiş okuma anlık görüntüsü (RCSI) veritabanı ayarı etkindir. Eşzamanlılığı artırmak için satır sürümü oluşturma kullanan RCSI altında, verileri okuyan oturumlar ve veri yazan oturumlar arasında engelleme en aza indirilir. Ancak, Azure SQL Veritabanındaki veritabanlarında engelleme ve kilitlenmeler oluşmaya devam edebilir çünkü:

  • Verileri değiştiren sorgular birbirlerini engelleyebilir.
  • Sorgular, engellemeyi artıran yalıtım düzeyleri altında çalıştırılabilir. Yalıtım düzeyleri Transact-SQL'de istemci kitaplığı yöntemleri, sorgu ipuçları veya SET deyimleri aracılığıyla belirtilebilir.
  • RCSI devre dışı bırakılabilir ve bu da veritabanının SELECT deyimlerini korumak için paylaşılan (S) kilitleri kullanmasına ve okuma işlemi yapılan yalıtım düzeyi altında çalışmasına neden olabilir. Bu, engelleme ve kilitlenmeleri artırabilir.

Örnek bir kilitlenme

İki veya daha fazla görev birbirini kalıcı olarak engellediğinde kilitlenme oluşur çünkü her görevin diğer görevin kilitlemeye çalıştığı bir kaynak üzerinde kilidi vardır. Kilitlenme, döngüsel bağımlılık olarak da adlandırılır: İki görevli kilitlenme durumunda, A işleminin B işlemine bağımlılığı vardır ve B işlemi A işlemine bağımlılık oluşturarak daireyi kapatır.

Örnek:

  1. A Oturumu açık bir işlem başlatır ve tablodaki SalesLT.Product bir satırda özel (X) kilide dönüştürülen bir güncelleştirme (U) kilidi alan bir güncelleştirme deyimi çalıştırır.
  2. Oturum B , tabloyu değiştiren SalesLT.ProductDescription bir güncelleştirme deyimi çalıştırır. Update deyimi, güncelleştirilecek SalesLT.Product doğru satırları bulmak için tabloya katılır.
    • Oturum B , tablodaki 72 satırda SalesLT.ProductDescription bir güncelleştirme (U) kilidi alır.
    • Oturum B, A Oturumu tarafından kilitlenen satır da dahil olmak üzere tablodaki SalesLT.Productsatırlarda paylaşılan bir kilit gerekir. Oturum B üzerinde SalesLT.Productengellendi.
  3. A oturumu işlemine devam eder ve şimdi tabloda bir güncelleştirme SalesLT.ProductDescription çalıştırır. A Oturumu , üzerindeki SalesLT.ProductDescriptionOturum B tarafından engellendi.

Kilitlenmede iki oturumu gösteren diyagram. Her oturum, devam etmek için diğer işlemin ihtiyaç duyduğu bir kaynağa sahip.

Örneğin oturumu sonlandırıldığı için katılan işlemlerden biri geri alınmadığı sürece kilitlenme durumundaki tüm işlemler süresiz olarak bekler.

Veritabanı altyapısı kilitlenme izleyicisi, kilitlenme içindeki görevleri düzenli aralıklarla denetler. Kilitlenme izleyicisi döngüsel bir bağımlılık algılarsa, görevlerden birini kurban olarak seçer ve işlemini 1205 hatasıyla sonlandırır: "İşlem (İşlem Kimliği N), kilit kaynaklarında başka bir işlemle kilitlendi ve kilitlenme kurbanı olarak seçildi. İşlemi yeniden çalıştırın." Kilitlenmeyi bu şekilde bozmak, kilitlenmedeki diğer görev veya görevlerin işlemlerini tamamlamasına olanak tanır.

Not

Bu makalenin Kilitlenme işlemi listesi bölümünde kilitlenme kurbanı seçme ölçütleri hakkında daha fazla bilgi edinin.

İki oturum arasındaki kilitlenmeye genel bakış. Kilitlenme kurbanı olarak bir oturum seçildi.

Kilitlenme kurbanı olarak seçilen işlemle uygulamanın işlemi yeniden denemesi gerekir ve bu işlem genellikle kilitlenmeye dahil olan diğer işlem veya işlemler tamamlandıktan sonra tamamlar.

Aynı kilitlenmeyle yeniden karşılaşmamak için yeniden denemeden önce kısa, rastgele bir gecikme uygulamak en iyi uygulamadır. Geçici hatalar için yeniden deneme mantığı tasarlama hakkında daha fazla bilgi edinin.

Azure SQL Veritabanında varsayılan yalıtım düzeyi

Azure SQL Veritabanındaki yeni veritabanları varsayılan olarak okuma işlemi yapılan anlık görüntüyü (RCSI) etkinleştirir. RCSI, SELECT deyimleri için paylaşılan (S) kilitleri kullanılmadan deyim düzeyinde tutarlılık sağlamak üzere satır sürümü oluşturma kullanmak üzere okundu yalıtım düzeyinin davranışını değiştirir.

RCSI etkinken:

  • Verileri okuyan deyimler, verileri değiştiren deyimleri engellemez.
  • Verileri değiştiren deyimler, verileri okuyan deyimleri engellemez.

Anlık görüntü yalıtım düzeyi, Azure SQL Veritabanındaki yeni veritabanları için de varsayılan olarak etkindir. Anlık görüntü yalıtımı, veriler için işlem düzeyi tutarlılığı sağlayan ve güncelleştirilecek satırları seçmek için satır sürümlerini kullanan ek bir satır tabanlı yalıtım düzeyidir. Anlık görüntü yalıtımını kullanmak için sorguların veya bağlantıların işlem yalıtım düzeyini açıkça olarak SNAPSHOTolarak ayarlaması gerekir. Bu yalnızca veritabanı için anlık görüntü yalıtımı etkinleştirildiğinde yapılabilir.

RCSI ve/veya anlık görüntü yalıtımının Transact-SQL ile etkinleştirilip etkinleştirilmediğini belirleyebilirsiniz. Azure SQL Veritabanı'nda veritabanınıza bağlanın ve aşağıdaki sorguyu çalıştırın:

SELECT name, is_read_committed_snapshot_on, snapshot_isolation_state_desc
FROM sys.databases
WHERE name = DB_NAME();
GO

RCSI etkinleştirilirse sütun is_read_committed_snapshot_on1 değerini döndürür. Anlık görüntü yalıtımı etkinleştirilirse sütun snapshot_isolation_state_descON değerini döndürür.

Azure SQL Veritabanındaki bir veritabanı için RCSI devre dışı bırakıldıysa, yeniden etkinleştirmeden önce RCSI'nin neden devre dışı bırakıldığını araştırın. Uygulama kodu, veri yazan sorgular tarafından veri okuyan sorguların engellenmesi ve RCSI etkinleştirildiğinde yarış koşullarından kaynaklanan yanlış sonuçlarla sonuçlanması beklenirken yazılmış olabilir.

Kilitlenme olaylarını yorumlama

Azure SQL Veritabanındaki kilitlenme yöneticisi bir kilitlenme algıladıktan ve bir işlemi kurban olarak seçtikten sonra bir kilitlenme olayı yayılır. Başka bir deyişle, kilitlenme uyarıları ayarlarsanız, tek bir kilitlenme çözüldükten sonra bildirim tetiklenir. Bu kilitlenme için yapılması gereken bir kullanıcı eylemi yoktur. Uygulamalar, 1205 hatasını aldıktan sonra otomatik olarak devam edebilmeleri için yeniden deneme mantığını içerecek şekilde yazılmalıdır: "İşlem (İşlem Kimliği N), kilit kaynaklarında başka bir işlemle kilitlendi ve kilitlenme kurbanı olarak seçildi. İşlemi yeniden çalıştırın."

Ancak kilitlenmeler yeniden oluşaa olabileceği için uyarıları ayarlamak yararlı olur. Kilitlenme uyarıları, veritabanınızda yinelenen kilitlenmeler olup olmadığını araştırmanıza olanak tanır ve bu durumda kilitlenmelerin yeniden oluşmasını önlemek için eylem gerçekleştirmeyi seçebilirsiniz. Uyarı oluşturma hakkında daha fazla bilgi edinmek için bu makalenin kilitlenmeleri izleme ve uyarı oluşturma bölümünden bilgi edinin.

Kilitlenmeleri önlemeye yönelik en iyi yöntemler

Kilitlenmelerin yeniden oluşmasını önlemeye yönelik en düşük risk yaklaşımı genellikle kilitlenmeye dahil olan sorguları iyileştirmek için kümelenmemiş dizinleri ayarlamaktır .

  • Kümelenmemiş dizinlerin ayarlanması sorgu kodunun kendisinde değişiklik gerektirmediğinden ve Transact-SQL yeniden yazılırken kullanıcıya yanlış veri döndürülmesine neden olan bir kullanıcı hatası riskini azalttığı için bu yaklaşım için risk düşüktür.
  • Etkili bir kümelenmemiş dizin ayarı, sorguların okunacak ve değiştirecek verileri daha verimli bir şekilde bulmasına yardımcı olur. Bir sorgunun erişmesi gereken veri miktarını azaltarak engelleme olasılığı azalır ve kilitlenmeler genellikle önlenebilir.

Bazı durumlarda, kümelenmiş dizin oluşturmak veya ayarlamak engelleme ve kilitlenmeleri azaltabilir. Kümelenmiş dizin tüm kümelenmemiş dizin tanımlarına dahil edildiğinden, kümelenmiş dizin oluşturma veya değiştirme işlemi, mevcut kümelenmemiş dizinlere sahip daha büyük tablolarda GÇ yoğunluklu ve zaman alan bir işlem olabilir. Kümelenmiş dizin tasarımı yönergeleri hakkında daha fazla bilgi edinin.

Dizin ayarlama, kilitlenmeleri önlemede başarılı olmadığında başka yöntemler de kullanılabilir:

  • Kilitlenme yalnızca kilitlenmeye dahil olan sorgulardan biri için belirli bir plan seçildiğinde oluşursa, Sorgu Deposu ile bir sorgu planını zorlamak kilitlenmelerin yeniden oluşmasını engelleyebilir.
  • Kilitlenmeye dahil olan bir veya daha fazla işlem için Transact-SQL'in yeniden yazılması da kilitlenmeleri önlemeye yardımcı olabilir. Açık işlemleri daha küçük işlemlere bölmek, eşzamanlı değişiklikler gerçekleştiğinde veri geçerliliğini sağlamak için dikkatli bir kodlama ve test gerektirir.

Bu yaklaşımların her biri hakkında daha fazla bilgi için bu makalenin Kilitlenmenin yeniden oluşmasını engelleme bölümünden bilgi edinin.

Kilitlenmeleri izleme ve uyarı

Bu makalede, kilitlenme uyarıları ayarlamak, örnek bir kilitlenmeye neden olmak, örnek kilitlenme için kilitlenme grafiğini analiz etmek ve kilitlenmenin yeniden oluşmasını önlemek için değişiklikleri test etmek için örnek veritabanını kullanacağız AdventureWorksLT .

Bu makaledeki SQL Server Management Studio (SSMS) istemcisini kullanacağız çünkü kilitlenme grafiklerini etkileşimli bir görsel modda görüntüleme işlevselliği içerir. Örnekleri takip etmek için Azure Data Studio gibi diğer istemcileri kullanabilirsiniz, ancak kilitlenme grafiklerini yalnızca XML olarak görüntüleyebilirsiniz.

AdventureWorksLT veritabanını oluşturma

Örnekleri takip etmek için Azure SQL Veritabanı'nda yeni bir veritabanı oluşturun ve Veri kaynağı olarak Örnek veriler'i seçin.

Azure portal, Azure CLI veya PowerShell ile oluşturma AdventureWorksLT hakkında ayrıntılı yönergeler için Hızlı Başlangıç: Azure SQL Veritabanı tek veritabanı oluşturma başlığı altında tercih edilen yaklaşımı seçin.

Azure portal kilitlenme uyarılarını ayarlama

Kilitlenme olaylarına yönelik uyarılar ayarlamak için Azure portal kullanarak Azure SQL Veritabanı ve Azure Synapse Analytics için uyarılar oluşturma makalesindeki adımları izleyin.

Uyarının sinyal adı olarak Kilitlenmeler'i seçin. eylem grubunu, Email/SMS/Push/Voice eylem türü gibi tercih ettiğiniz yöntemi kullanarak sizi bilgilendirecek şekilde yapılandırın.

Genişletilmiş Olaylarla Azure SQL Veritabanında kilitlenme grafiklerini toplama

Kilitlenme grafikleri, kilitlenmeye neden olan işlemler ve kilitlerle ilgili zengin bir bilgi kaynağıdır. Azure SQL Veritabanında Genişletilmiş Olaylar (XEvents) ile kilitlenme grafikleri toplamak için olayı yakalayınsqlserver.database_xml_deadlock_report.

Kademe arabelleği hedefini veya olay dosyası hedefini kullanarak XEvents ile kilitlenme grafikleri toplayabilirsiniz. Uygun hedef türünü seçmeyle ilgili dikkat edilmesi gerekenler aşağıdaki tabloda özetlenir:

Yaklaşım Avantajlar Dikkat edilmesi gerekenler Kullanım senaryoları
Kademe arabelleği hedefi
  • Yalnızca Transact-SQL ile basit kurulum.
  • XEvents oturumu veritabanını çevrimdışına alma veya veritabanı yük devretme gibi herhangi bir nedenle durdurulduğunda olay verileri temizlenir.
  • Veritabanı kaynakları, halka arabelleğindeki verileri korumak ve oturum verilerini sorgulamak için kullanılır.
  • Test ve öğrenme için örnek izleme verileri toplayın.
  • Hemen bir olay dosyası hedefi kullanarak oturum ayarlayamıyorsanız, kısa vadeli gereksinimler için oluşturun.
  • İzleme verilerini bir tabloda kalıcı hale getirmek için otomatik bir işlem ayarladığınızda izleme verileri için "giriş paneli" olarak kullanın.
Olay dosyası hedefi
  • Oturum durdurulduktan sonra bile verilerin kullanılabilir olması için olay verilerini Azure Depolama'daki bir blobda kalıcı hale alır.
  • Olay dosyaları Azure portal veya Azure Depolama Gezgini indirilebilir ve yerel olarak analiz edilebilir ve bu da oturum verilerini sorgulamak için veritabanı kaynaklarının kullanılmasını gerektirmez.
  • Kurulum daha karmaşıktır ve Azure Depolama kapsayıcısının ve veritabanı kapsamlı kimlik bilgilerinin yapılandırılması gerekir.
  • Olay oturumu durdurulduğunda bile olay verilerinin kalıcı olmasını istediğinizde genel kullanım.
  • Bellekte kalıcı olmasını istediğinizden daha fazla miktarda olay verisi oluşturan bir izleme çalıştırmak istiyorsunuz.

Kullanmak istediğiniz hedef türü seçin:

Halka arabelleği hedefi kolay ve kurulumu kolaydır, ancak sınırlı kapasiteye sahiptir ve bu da eski olayların kaybolmasına neden olabilir. Kademe arabelleği olayları depolamada kalıcı yapmaz ve XEvents oturumu durdurulduğunda kademe arabelleği hedefi temizlenir. Bu, veritabanı altyapısı yük devretme gibi herhangi bir nedenle yeniden başlatıldığında toplanan XEvent'lerin kullanılamayacağı anlamına gelir. Kademe arabelleği hedefi, hemen bir olay dosyası hedefine XEvents oturumu ayarlama olanağınız yoksa öğrenmeye ve kısa vadeli gereksinimlere en uygun yöntemdir.

Bu örnek kod , kademe arabelleği hedefini kullanarak bellekteki kilitlenme grafiklerini yakalayan bir XEvents oturumu oluşturur. Kademe arabelleği hedefi için izin verilen bellek üst sınırı 4 MB'tır ve veritabanı çevrimiçi olduğunda ,örneğin yük devretme sonrasında oturum otomatik olarak çalışır.

Halka arabellek hedefine yazan olay için bir XEvents oturumu oluşturup başlatmak için sqlserver.database_xml_deadlock_report veritabanınıza bağlanın ve aşağıdaki Transact-SQL'i çalıştırın:

CREATE EVENT SESSION [deadlocks] ON DATABASE 
ADD EVENT sqlserver.database_xml_deadlock_report
ADD TARGET package0.ring_buffer 
WITH (STARTUP_STATE=ON, MAX_MEMORY=4 MB)
GO

ALTER EVENT SESSION [deadlocks] ON DATABASE
    STATE = START;
GO

AdventureWorksLT'de kilitlenmeye neden olur

Not

Bu örnek, RCSI etkinleştirildiğinde varsayılan şema ve verilerle AdventureWorksLT veritabanında çalışır. Veritabanını oluşturma yönergeleri için bkz . AdventureWorksLT veritabanı oluşturma.

Kilitlenmeye neden olmak için veritabanına iki oturum AdventureWorksLT bağlamanız gerekir. Bu oturumları Oturum A ve Oturum B olarak adlandıracağız.

A Oturumu'nda aşağıdaki Transact-SQL'i çalıştırın. Bu kod açık bir işlem başlatır ve tabloyu güncelleştiren SalesLT.Product tek bir deyim çalıştırır. Bunu yapmak için işlem, tablodaki SalesLT.Product bir satırda özel (X) kilide dönüştürülen bir güncelleştirme (U) kilidi alır. İşlemi açık bırakıyoruz.

BEGIN TRAN

    UPDATE SalesLT.Product SET SellEndDate = SellEndDate + 1
        WHERE Color = 'Red';

Şimdi, Oturum B'de aşağıdaki Transact-SQL'i çalıştırın. Bu kod açıkça işlem başlatmaz. Bunun yerine , otomatik işlem modunda çalışır. Bu deyim tabloyu güncelleştirir SalesLT.ProductDescription . Güncelleştirme, tablodaki 72 satırda SalesLT.ProductDescription bir güncelleştirme (U) kilidi alır. Sorgu, tablo da dahil olmak üzere diğer tablolara katılır SalesLT.Product .

UPDATE SalesLT.ProductDescription SET Description = Description
    FROM SalesLT.ProductDescription as pd
    JOIN SalesLT.ProductModelProductDescription as pmpd on
        pd.ProductDescriptionID = pmpd.ProductDescriptionID
    JOIN SalesLT.ProductModel as pm on
        pmpd.ProductModelID = pm.ProductModelID
    JOIN SalesLT.Product as p on
        pm.ProductModelID=p.ProductModelID
    WHERE p.Color = 'Silver';

Bu güncelleştirmeyi tamamlamak için, Oturum B'nin, A Oturumu tarafından kilitlenen satır da dahil olmak üzere tablodaki SalesLT.Productsatırlarda paylaşılan (S) kilidi olması gerekir. Oturum B üzerinde SalesLT.Productengellenir.

Oturum A'ya dönün. Aşağıdaki Transact-SQL deyimini çalıştırın. Bu, açık işlemin bir parçası olarak ikinci bir UPDATE deyimi çalıştırır.

	UPDATE SalesLT.ProductDescription SET Description = Description
		FROM SalesLT.ProductDescription as pd
		JOIN SalesLT.ProductModelProductDescription as pmpd on
			pd.ProductDescriptionID = pmpd.ProductDescriptionID
		JOIN SalesLT.ProductModel as pm on
			pmpd.ProductModelID = pm.ProductModelID
		JOIN SalesLT.Product as p on
			pm.ProductModelID=p.ProductModelID
		WHERE p.Color = 'Red';

Oturum A'daki ikinci güncelleştirme deyimi, üzerindeki SalesLT.ProductDescriptionOturum B tarafından engellenir.

Oturum A ve Oturum B artık birbirini karşılıklı olarak engelliyor. Her biri diğeri tarafından kilitlenmiş bir kaynağa ihtiyaç duyduğundan hiçbir işlem devam edebilir.

Birkaç saniye sonra kilitlenme izleyicisi, A Oturumu ve B Oturumu'ndaki işlemlerin birbirini karşılıklı olarak engellediğini ve ikisinin de ilerleme kaydedemeyeceklerini belirler. Kilitlenme kurbanı olarak Oturum A'nın seçildiğini içeren bir kilitlenmenin gerçekleştiğini görmeniz gerekir. A Oturumunda aşağıdakine benzer bir metin içeren bir hata iletisi görüntülenir:

Msg 1205, Düzey 13, Durum 51, Satır 7 İşlem (İşlem Kimliği 91), kilit kaynaklarında başka bir işlemle kilitlendi ve kilitlenme kurbanı olarak seçildi. İşlemi yeniden çalıştırın.

B oturumu başarıyla tamamlanır.

Azure portal kilitlenme uyarıları ayarladıysanız kilitlenme gerçekleştikten kısa süre sonra bir bildirim almanız gerekir.

XEvents oturumundaki kilitlenme grafiklerini görüntüleme

Kilitlenmeleri toplamak için bir XEvents oturumu ayarladıysanız ve oturum başlatıldıktan sonra bir kilitlenme oluştuysa, kilitlenme grafiğinin etkileşimli grafik görüntüsünü ve kilitlenme grafiğinin XML'sini görüntüleyebilirsiniz.

Kademe arabelleği hedefi ve olay dosyası hedefleri için kilitlenme bilgilerini almak için farklı yöntemler kullanılabilir. XEvents oturumunuz için kullandığınız hedefi seçin:

Kademe arabelleğine yazan bir XEvents oturumu ayarlarsanız, aşağıdaki Transact-SQL ile kilitlenme bilgilerini sorgulayabilirsiniz. Sorguyu çalıştırmadan önce değerini @tracename xEvents oturumunuzun adıyla değiştirin.

DECLARE @tracename sysname = N'deadlocks';

WITH ring_buffer AS (
	SELECT CAST(target_data AS XML) as rb
	FROM sys.dm_xe_database_sessions AS s 
	JOIN sys.dm_xe_database_session_targets AS t 
		ON CAST(t.event_session_address AS BINARY(8)) = CAST(s.address AS BINARY(8))
	WHERE s.name = @tracename and
	t.target_name = N'ring_buffer'
), dx AS (
	SELECT 
		dxdr.evtdata.query('.') as deadlock_xml_deadlock_report
	FROM ring_buffer
	CROSS APPLY rb.nodes('/RingBufferTarget/event[@name=''database_xml_deadlock_report'']') AS dxdr(evtdata)
) 
SELECT 
	d.query('/event/data[@name=''deadlock_cycle_id'']/value').value('(/value)[1]', 'int') AS [deadlock_cycle_id],
	d.value('(/event/@timestamp)[1]', 'DateTime2') AS [deadlock_timestamp],
	d.query('/event/data[@name=''database_name'']/value').value('(/value)[1]', 'nvarchar(256)') AS [database_name],
	d.query('/event/data[@name=''xml_report'']/value/deadlock') AS deadlock_xml,
	LTRIM(RTRIM(REPLACE(REPLACE(d.value('.', 'nvarchar(2000)'),CHAR(10),' '),CHAR(13),' '))) as query_text
FROM dx
CROSS APPLY deadlock_xml_deadlock_report.nodes('(/event/data/value/deadlock/process-list/process/inputbuf)') AS ib(d)
ORDER BY [deadlock_timestamp] DESC;
GO

XML'de kilitlenme grafiğini görüntüleme ve kaydetme

Kilitlenme grafiğini XML biçiminde görüntülemek, kilitlenmeye inputbuffer dahil olan Transact-SQL deyimlerini kopyalamanıza olanak tanır. Kilitlenmeleri metin tabanlı bir biçimde çözümlemeyi de tercih edebilirsiniz.

Kilitlenme grafı bilgilerini döndürmek için transact-SQL sorgusu kullandıysanız, kilitlenme grafı XML'sini görüntülemek için herhangi bir satırdaki sütundaki deadlock_xml değeri seçerek kilitlenme grafiğinin XML'sini SSMS'de yeni bir pencerede açın.

Bu örnek kilitlenme grafı için XML şöyledir:

<deadlock>
  <victim-list>
    <victimProcess id="process24756e75088" />
  </victim-list>
  <process-list>
    <process id="process24756e75088" taskpriority="0" logused="6528" waitresource="KEY: 8:72057594045202432 (98ec012aa510)" waittime="192" ownerId="1011123" transactionname="user_transaction" lasttranstarted="2022-03-08T15:44:43.490" XDES="0x2475c980428" lockMode="U" schedulerid="3" kpid="30192" status="suspended" spid="89" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2022-03-08T15:44:49.250" lastbatchcompleted="2022-03-08T15:44:49.210" lastattention="1900-01-01T00:00:00.210" clientapp="Microsoft SQL Server Management Studio - Query" hostname="LAPTOP-CHRISQ" hostpid="16716" loginname="chrisqpublic" isolationlevel="read committed (2)" xactid="1011123" currentdb="8" currentdbname="AdventureWorksLT" lockTimeout="4294967295" clientoption1="671096864" clientoption2="128056">
      <executionStack>
        <frame procname="unknown" queryhash="0xef52b103e8b9b8ca" queryplanhash="0x02b0f58d7730f798" line="1" stmtstart="2" stmtend="792" sqlhandle="0x02000000c58b8f1e24e8f104a930776e21254b1771f92a520000000000000000000000000000000000000000">
unknown    </frame>
      </executionStack>
      <inputbuf>
	UPDATE SalesLT.ProductDescription SET Description = Description
		FROM SalesLT.ProductDescription as pd
		JOIN SalesLT.ProductModelProductDescription as pmpd on
			pd.ProductDescriptionID = pmpd.ProductDescriptionID
		JOIN SalesLT.ProductModel as pm on
			pmpd.ProductModelID = pm.ProductModelID
		JOIN SalesLT.Product as p on
			pm.ProductModelID=p.ProductModelID
		WHERE p.Color = 'Red'   </inputbuf>
    </process>
    <process id="process2476d07d088" taskpriority="0" logused="11360" waitresource="KEY: 8:72057594045267968 (39e18040972e)" waittime="2641" ownerId="1013536" transactionname="UPDATE" lasttranstarted="2022-03-08T15:44:46.807" XDES="0x2475ca80428" lockMode="S" schedulerid="2" kpid="94040" status="suspended" spid="95" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2022-03-08T15:44:46.807" lastbatchcompleted="2022-03-08T15:44:46.760" lastattention="1900-01-01T00:00:00.760" clientapp="Microsoft SQL Server Management Studio - Query" hostname="LAPTOP-CHRISQ" hostpid="16716" loginname="chrisqpublic" isolationlevel="read committed (2)" xactid="1013536" currentdb="8" currentdbname="AdventureWorksLT" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056">
      <executionStack>
        <frame procname="unknown" queryhash="0xef52b103e8b9b8ca" queryplanhash="0x02b0f58d7730f798" line="1" stmtstart="2" stmtend="798" sqlhandle="0x020000002c85bb06327c0852c0be840fc1e30efce2b7c8090000000000000000000000000000000000000000">
unknown    </frame>
      </executionStack>
      <inputbuf>
	UPDATE SalesLT.ProductDescription SET Description = Description
		FROM SalesLT.ProductDescription as pd
		JOIN SalesLT.ProductModelProductDescription as pmpd on
			pd.ProductDescriptionID = pmpd.ProductDescriptionID
		JOIN SalesLT.ProductModel as pm on
			pmpd.ProductModelID = pm.ProductModelID
		JOIN SalesLT.Product as p on
			pm.ProductModelID=p.ProductModelID
		WHERE p.Color = 'Silver';   </inputbuf>
    </process>
  </process-list>
  <resource-list>
    <keylock hobtid="72057594045202432" dbid="8" objectname="9e011567-2446-4213-9617-bad2624ccc30.SalesLT.ProductDescription" indexname="PK_ProductDescription_ProductDescriptionID" id="lock2474df12080" mode="U" associatedObjectId="72057594045202432">
      <owner-list>
        <owner id="process2476d07d088" mode="U" />
      </owner-list>
      <waiter-list>
        <waiter id="process24756e75088" mode="U" requestType="wait" />
      </waiter-list>
    </keylock>
    <keylock hobtid="72057594045267968" dbid="8" objectname="9e011567-2446-4213-9617-bad2624ccc30.SalesLT.Product" indexname="PK_Product_ProductID" id="lock2474b588580" mode="X" associatedObjectId="72057594045267968">
      <owner-list>
        <owner id="process24756e75088" mode="X" />
      </owner-list>
      <waiter-list>
        <waiter id="process2476d07d088" mode="S" requestType="wait" />
      </waiter-list>
    </keylock>
  </resource-list>
</deadlock>

Kilitlenme grafiğini XML dosyası olarak kaydetmek için:

  1. Dosya ve Farklı Kaydet... seçeneğini belirleyin.
  2. Kayıt türü değerini varsayılan XML Dosyaları (*.xml) olarak bırakın
  3. Dosya adı'nı istediğiniz ada ayarlayın.
  4. Kaydet’i seçin.

Kilitlenme grafiğini SSMS'de etkileşimli olarak görüntülenebilen bir XDL dosyası olarak kaydetme

Kilitlenme grafiğinin etkileşimli bir gösterimini görüntülemek, kilitlenmeye dahil olan işlemlere ve kaynaklara hızlı bir genel bakış elde etmek ve kilitlenme kurbanını hızlı bir şekilde tanımlamak için yararlı olabilir.

Kilitlenme grafiğini SSMS tarafından grafik olarak görüntülenebilen bir dosya olarak kaydetmek için:

  1. Kilitlenme grafiğinin deadlock_xml XML dosyasını SSMS'de yeni bir pencerede açmak için herhangi bir satırdan sütundaki değeri seçin.

  2. Dosya ve Farklı Kaydet... seçeneğini belirleyin.

  3. Kayıt türü'nüTüm Dosyalar olarak ayarlayın.

  4. Dosya adı'nı istediğiniz ada, uzantı ise .xdl olarak ayarlayın.

  5. Kaydet’i seçin.

    SSMS'de kilitlenme grafı XML dosyasını xsd uzantısına sahip bir dosyaya kaydetme işleminin ekran görüntüsü.

  6. Pencerenin üst kısmındaki sekmede X işaretini seçerek veya Dosya'yı ve ardından Kapat'ı seçerek dosyayı kapatın.

  7. SSMS'de Dosya'yı ve ardından Aç'ı ve ardından Dosya'yı seçerek dosyayı yeniden açın. Uzantıyla .xdl kaydettiğiniz dosyayı seçin.

    Kilitlenme grafı artık SSMS'de kilitlenmeye dahil olan işlemlerin ve kaynakların görsel bir gösterimiyle görüntülenir.

    SSMS'de açılan bir xdl dosyasının ekran görüntüsü. Kilitlenme grafı, ovaller tarafından gösterilen işlemler ve kaynakları dikdörtgenler olarak kilitleyerek grafik olarak görüntülenir.

Azure SQL Veritabanı için kilitlenmeyi analiz etme

Kilitlenme grafiği genellikle üç düğüme sahiptir:

  • Kurban listesi. Kilitlenme kurbanı işlem tanımlayıcısı.
  • İşlem listesi. Kilitlenmeye dahil olan tüm işlemler hakkında bilgi. Kilitlenme grafikleri, işlem çalıştıran bir oturumu temsil etmek için 'process' terimini kullanır.
  • Kaynak listesi. Kilitlenmeye dahil olan kaynaklar hakkında bilgi.

Kilitlenmeyi analiz ederken bu düğümlerde adım adım gezinmek yararlı olur.

Kilitlenme kurbanı listesi

Kilitlenme kurbanı listesi, kilitlenme kurbanı olarak seçilen işlemi gösterir. Kilitlenme grafiğinin görsel gösteriminde işlemler ovallerle temsil edilir. Kilitlenme kurbanı işlemi oval üzerine bir "X" çizilmiş.

Kilitlenmenin görsel görüntüsünün ekran görüntüsü. Kurban olarak seçilen işlemi temsil eden ovalin üzerinde bir X çizilmiş.

Bir kilitlenme grafiğinin XML görünümünde düğüm, victim-list kilitlenmenin kurbanı olan işlem için bir kimlik verir.

Örnek kilitlenmemizde, kurban işlem kimliği process24756e75088 şeklindedir. Bu kimliği, işlem listesi ve kaynak listesi düğümlerini inceleyerek kurban işlemi ve kilitlendiği veya kilitlenmesini istediği kaynaklar hakkında daha fazla bilgi edinmek için kullanabiliriz.

Kilitlenme işlemi listesi

Kilitlenme işlemi listesi, kilitlenmeye dahil olan işlemler hakkında zengin bir bilgi kaynağıdır.

Kilitlenme grafiğinin grafik gösterimi, kilitlenme grafiği XML'sinde yer alan bilgilerin yalnızca bir alt kümesini gösterir. Kilitlenme grafiğindeki ovaller işlemi temsil eder ve aşağıdakileri içeren bilgileri gösterir:

  • Oturum kimliği veya SPID olarak da bilinen sunucu işlem kimliği.

  • Oturumun kilitlenme önceliği. İki oturumun farklı kilitlenme öncelikleri varsa, düşük önceliğe sahip oturum kilitlenme kurbanı olarak seçilir. Bu örnekte, her iki oturum da aynı kilitlenme önceliğine sahiptir.

  • Oturum tarafından bayt cinsinden kullanılan işlem günlüğü miktarı. Her iki oturum da aynı kilitlenme önceliğine sahipse, kilitlenme izleyicisi kilitlenme kurbanı olarak geri alınması daha ucuz olan oturumu seçer. Maliyet, her işlemdeki bu noktaya yazılan günlük baytlarının sayısı karşılaştırılarak belirlenir.

    Örneğimizde, session_id 89 daha düşük miktarda işlem günlüğü kullanmış ve kilitlenme kurbanı olarak seçilmişti.

Buna ek olarak, kilitlenmeden önce her oturumda çalıştırılan son deyimin giriş arabelleğine fareyi her işlemin üzerine getirerek görüntüleyebilirsiniz. Giriş arabelleği bir araç ipucunda görünür.

SSMS'de görsel olarak görüntülenen kilitlenme grafiğinin ekran görüntüsü. İki oval işlemleri temsil eder. Bir işlem için inputbuff gösterilir.

Kilitlenme grafiğinin XML görünümündeki işlemler için aşağıdakiler gibi ek bilgiler sağlanır:

  • Oturum için istemci adı, ana bilgisayar adı ve oturum açma adı gibi bilgileri tanımlama.
  • Kilitlenmeden önce her oturum tarafından çalıştırılan son deyim için sorgu planı karması. Sorgu planı karması, Sorgu Deposu'ndan sorgu hakkında daha fazla bilgi almak için kullanışlıdır.

Örneğimizde kilitlenme:

  • Her iki oturumun da chrisqpublic oturum açma bilgileri altındaki SSMS istemcisi kullanılarak çalıştırıldığını görebiliriz.
  • Kilitlenme kurbanımız tarafından kilitlenmeden önce çalıştırılan son deyimin sorgu planı karması 0x02b0f58d7730f798. Giriş arabelleğinde bu deyimin metnini görebiliriz.
  • Kilitlenmemizdeki diğer oturum tarafından çalıştırılan son deyimin sorgu planı karması da 0x02b0f58d7730f798. Giriş arabelleğinde bu deyimin metnini görebiliriz. Bu durumda, eşitlik koşulu olarak kullanılan değişmez değer dışında sorgular aynı olduğundan her iki sorgu da aynı sorgu planı karması içerir.

Sorgu Deposu'nda ek bilgi bulmak için bu değerleri bu makalenin ilerleyen bölümlerinde kullanacağız.

Kilitlenme işlemi listesindeki giriş arabelleğinin sınırlamaları

Kilitlenme işlemi listesindeki giriş arabelleği bilgileriyle ilgili dikkat edilmesi gereken bazı sınırlamalar vardır.

Sorgu metni giriş arabelleğinde kesilebilir. Giriş arabelleği yürütülmekte olan deyimin ilk 4.000 karakteriyle sınırlıdır.

Buna ek olarak, kilitlenmeye dahil olan bazı deyimler kilitlenme grafında yer almayabilir. Bizim örneğimizde, Oturum A tek bir işlem içinde iki güncelleştirme deyimi çalıştırmıştır. Kilitlenmeye neden olan güncelleştirme olan yalnızca ikinci güncelleştirme deyimi kilitlenme grafiğine dahil edilir. A Oturumu tarafından çalıştırılan ilk güncelleştirme deyimi, Oturum B'yi engelleyerek kilitlenmede bir rol oynadı. Oturum A tarafından çalıştırılan ilk deyimin giriş arabelleği, query_hashve ilgili bilgileri kilitlenme grafiğine dahil değildir.

Kilitlenmeye dahil olan çok deyimli bir işlemde transact-SQL çalıştırmasının tamamını tanımlamak için, sorguyu çalıştıran saklı yordam veya uygulama kodunda ilgili bilgileri bulmanız veya kilitlenme sırasında kilitlenmeye dahil olan oturumlar tarafından çalıştırılan tam deyimleri yakalamak için Genişletilmiş Olaylar kullanarak bir izleme çalıştırmanız gerekir. Kilitlenmeye dahil olan bir deyim kesilmişse ve giriş arabelleğinde yalnızca kısmi Transact-SQL görünüyorsa, Deyimin Transact-SQL'ini Yürütme Planı ile Sorgu Deposu'nda bulabilirsiniz.

Kilitlenme kaynak listesi

Kilitlenme kaynak listesi, kilitlenmedeki işlemlerin hangi kilit kaynaklarının sahibi olduğunu ve beklediğini gösterir.

Kaynaklar, kilitlenmenin görsel gösteriminde dikdörtgenlerle temsil edilir:

SSMS'de görsel olarak görüntülenen kilitlenme grafiğinin ekran görüntüsü. Dikdörtgenler kilitlenmeye dahil olan kaynakları gösterir.

Not

Veritabanı adlarının, Azure SQL Veritabanındaki veritabanları için kilitlenme grafiklerinde benzersizdeğerler olarak gösterildiğini fark edebilirsiniz. Bu, physical_database_namesys.databases ve sys.dm_user_db_resource_governance dinamik yönetim görünümlerinde listelenen veritabanına yöneliktir.

Bu örnekte kilitlenme:

  • Oturum A olarak belirttiğimiz kilitlenme kurbanı:

    • Tablodaki dizindeki bir anahtar üzerinde PK_Product_ProductID özel (X) kilidi vardır SalesLT.Product .
    • Tablodaki dizindeki SalesLT.ProductDescription bir anahtara PK_ProductDescription_ProductDescriptionID güncelleştirme (U) kilidi ister.
  • Oturum B olarak adlandırılan diğer işlem:

    • Tablodaki dizindeki bir anahtar üzerinde PK_ProductDescription_ProductDescriptionID bir güncelleştirme (U) kilidine SalesLT.ProductDescription sahip.
    • Tablodaki dizindeki SalesLT.ProductDescription bir anahtar üzerinde PK_ProductDescription_ProductDescriptionID paylaşılan (S) kilidi ister.

Aynı bilgileri kaynak listesi düğümündeki kilitlenme grafiğinin XML'sinde de görebiliriz.

Sorgu Deposu'nda sorgu yürütme planlarını bulma

Genellikle kilitlenmeye dahil olan deyimler için sorgu yürütme planlarını incelemek yararlı olur. Bu yürütme planları genellikle kilitlenme grafiğinin işlem listesinin XML görünümünden sorgu planı karması kullanılarak Sorgu Deposu'nda bulunabilir.

Bu Transact-SQL sorgusu, örnek kilitlenme için bulduğumuz sorgu planı karmasıyla eşleşen sorgu planlarını arar. Sorguyu çalıştırmak için Azure SQL Veritabanındaki kullanıcı veritabanına bağlanın.

DECLARE @query_plan_hash binary(8) = 0x02b0f58d7730f798

SELECT 
	qrsi.end_time as interval_end_time,
	qs.query_id,
	qp.plan_id,
	qt.query_sql_text, 
	TRY_CAST(qp.query_plan as XML) as query_plan,
	qrs.count_executions
FROM sys.query_store_query as qs
JOIN sys.query_store_query_text as qt on qs.query_text_id=qt.query_text_id
JOIN sys.query_store_plan as qp on qs.query_id=qp.query_id
JOIN sys.query_store_runtime_stats qrs on qp.plan_id = qrs.plan_id
JOIN sys.query_store_runtime_stats_interval qrsi on qrs.runtime_stats_interval_id=qrsi.runtime_stats_interval_id
WHERE query_plan_hash =  @query_plan_hash
ORDER BY interval_end_time, query_id;
GO

Sorgu Deposu CLEANUP_POLICY veya QUERY_CAPTURE_MODE ayarlarınıza bağlı olarak Sorgu Deposu'ndan sorgu yürütme planı alamayabilirsiniz. Bu durumda, sorgu için tahmini yürütme planını görüntüleyerek genellikle gerekli bilgileri alabilirsiniz.

Engellemeyi artıran desenleri arayın

Kilitlenmelerle ilgili sorgu yürütme planlarını incelerken engelleme ve kilitlenmelere katkıda bulunabilecek desenlere dikkat edin.

  • Tablo veya dizin taramaları. Verileri değiştiren sorgular RCSI altında çalıştırıldığında, güncelleştirilecek satırların seçimi, veri değerleri okundukça veri satırında bir güncelleştirme (U) kilidi alındığı bir engelleme taraması kullanılarak yapılır. Veri satırı güncelleştirme ölçütlerini karşılamıyorsa güncelleştirme kilidi serbest bırakılır ve sonraki satır kilitlenir ve taranır.

    Değişiklik sorgularının satırları daha verimli bulmasına yardımcı olmak için dizinlerin ayarlanması, verilen güncelleştirme kilitlerinin sayısını azaltır. Bu, engelleme ve kilitlenme olasılığını azaltır.

  • Birden fazla tabloya başvuran dizinlenmiş görünümler. Dizinli görünümde başvuruda bulunan bir tabloyu değiştirdiğinizde, veritabanı altyapısının da dizinlenmiş görünümü koruması gerekir. Bu, daha fazla kilit almayı gerektirir ve engelleme ve kilitlenmelerin artmasına neden olabilir. Dizine alınan görünümler, güncelleştirme işlemlerinin okuma kaydedilmiş yalıtım düzeyi altında dahili olarak yürütülmesine de neden olabilir.

  • Yabancı anahtar kısıtlamalarında başvuruda bulunan sütunlarda yapılan değişiklikler. YABANCı ANAHTAR kısıtlamasında başvuruda bulunan bir tablodaki sütunları değiştirdiğinizde, veritabanı altyapısı başvuruda bulunan tabloda ilgili satırları aramalıdır. Bu okumalar için satır sürümleri kullanılamaz. Art arda güncelleştirmelerin veya silmelerin etkinleştirildiği durumlarda, hayalet eklemelere karşı koruma sağlamak için deyimin süresi boyunca yalıtım düzeyi serileştirilebilir duruma getirilebilir.

  • kilit ipuçları. Daha fazla kilit gerektiren yalıtım düzeylerini belirten tablo ipuçlarını arayın. Bu ipuçları ( HOLDLOCK serileştirilebilir ile eşdeğerdir), SERIALIZABLE, READCOMMITTEDLOCK (RCSI'yi devre dışı bırakır) ve REPEATABLEREADiçerir. Ayrıca, , TABLOCK, UPDLOCKve XLOCK gibi PAGLOCKipuçları engelleme ve kilitlenme risklerini artırabilir.

    Bu ipuçları mevcutsa ipuçlarının neden uygulandığını araştırın. Bu ipuçları yarış koşullarını engelleyebilir ve veri geçerliliğini güvence altına alabilir. Gerekirse, bu ipuçlarını yerinde bırakmak ve gerekirse bu makalenin Kilitlenmenin tekrarlanmasını önleme bölümünde alternatif bir yöntem kullanarak gelecekteki kilitlenmeleri önlemek mümkün olabilir.

    Not

    İşlem kilitleme ve satır sürümü oluşturma kılavuzunda satır sürümü oluşturma kullanarak verileri değiştirirken oluşan davranışlar hakkında daha fazla bilgi edinin.

Yürütme planında veya uygulama sorgu kodunda bir işlemin tam kodunu incelerken, ek sorunlu desenler arayın:

  • İşlemlerdeki kullanıcı etkileşimi. Açık bir çok deyimli işlem içindeki kullanıcı etkileşimi, işlemlerin süresini önemli ölçüde artırır. Bu, bu işlemlerin çakışması ve engelleme ve kilitlenmelerin oluşmasını daha olası hale getirir.

    Benzer şekilde, açık bir işlem tutmak ve ilgisiz bir veritabanı veya sistem orta işlemi sorgulamak engelleme ve kilitlenme olasılığını önemli ölçüde artırır.

  • Farklı siparişlerdeki nesnelere erişen işlemler. Eşzamanlı açık çok deyimli işlemler aynı desenleri izlediğinde ve nesnelere aynı sırayla eriştiğinde kilitlenmelerin oluşma olasılığı daha düşüktür.

Kilitlenmenin yeniden oluşmasını önleme

Dizin ayarlama, Sorgu Deposu ile planları zorlama ve Transact-SQL sorgularını değiştirme gibi kilitlenmelerin yeniden oluşmasını önlemek için kullanılabilecek birden çok teknik vardır.

  • Tablonun kümelenmiş dizinini gözden geçirin. Çoğu tablo kümelenmiş dizinlerden yararlansa da genellikle tablolar yanlışlıkla yığın olarak uygulanır.

    Kümelenmiş dizini denetlemenin bir yolu , sp_helpindex sistem saklı yordamını kullanmaktır. Örneğin, aşağıdaki deyimi yürüterek tablodaki SalesLT.Product dizinlerin özetini görüntüleyebiliriz:

    exec sp_helpindex 'SalesLT.Product';
    GO
    

    index_description sütununu gözden geçirin. Bir tabloda yalnızca bir kümelenmiş dizin olabilir. Tablo için kümelenmiş dizin uygulandıysa, index_description 'kümelenmiş' sözcüğünü içerir.

    Kümelenmiş dizin yoksa, tablo bir yığındır. Bu durumda, tablonun belirli bir performans sorununu çözmek için kasıtlı olarak yığın olarak oluşturulup oluşturulmadığını gözden geçirin. Kümelenmiş dizin tasarım yönergelerine göre kümelenmiş bir dizin uygulamayı göz önünde bulundurun.

    Bazı durumlarda kümelenmiş dizin oluşturma veya ayarlama, kilitlenmelerde engellemeyi azaltabilir veya ortadan kaldırabilir. Diğer durumlarda, bu listedeki diğerleri gibi ek bir teknik kullanmanız gerekebilir.

  • Kümelenmemiş dizinler oluşturun veya değiştirin. Kümelenmemiş dizinleri ayarlamak, değişiklik sorgularınızın güncelleştirme verilerini daha hızlı bulmasına yardımcı olabilir ve bu da gerekli güncelleştirme kilidi sayısını azaltır.

    Örneğimizde, Sorgu Deposu'nda bulunan sorgu yürütme planı dizine karşı PK_Product_ProductID kümelenmiş bir dizin taraması içerir. Kilitlenme grafiği, bu dizindeki paylaşılan (S) kilit beklemesinin kilitlenmedeki bir bileşen olduğunu gösterir.

    Sorgu yürütme planının ekran görüntüsü. Product tablosundaki PK_Product_ProductID dizininde kümelenmiş dizin taraması gerçekleştiriliyor.

    Güncelleştirme sorgumuzun adlı vProductAndDescriptiondizinlenmiş görünümü değiştirmesi gerektiğinden bu dizin taraması gerçekleştiriliyor. Bu makalenin Engellemeyi artıran desenleri arama bölümünde belirtildiği gibi, birden çok tabloya başvuran dizinli görünümler engellemeyi ve kilitlenme olasılığını artırabilir.

    Veritabanında dizinlenmiş görünüm tarafından başvurulan sütunları SalesLT.Product "kapsayan" aşağıdaki kümelenmemiş dizini AdventureWorksLT oluşturursak, bu sorgunun satırları çok daha verimli bulmasına yardımcı olur:

    CREATE INDEX ix_Product_ProductID_Name_ProductModelID on SalesLT.Product (ProductID, Name, ProductModelID);
    GO
    

    Bu dizini oluşturduktan sonra kilitlenme artık yeniden oluşmaz.

    Kilitlenmeler yabancı anahtar kısıtlamalarında başvuruda bulunılan sütunlarda değişiklik içeriyorsa, YABANCı ANAHTAR'ın başvuran tablosundaki dizinlerin ilgili satırları verimli bir şekilde bulmayı desteklediğinden emin olun.

    Dizinler bazı durumlarda sorgu performansını önemli ölçüde iyileştirebilir ancak dizinlerin ek yükü ve yönetim maliyetleri de vardır. Dizin oluşturmadan önce dizinlerin avantajını değerlendirmeye yardımcı olmak için, özellikle büyük tablolarda geniş dizinler ve dizinler olmak üzere genel dizin tasarımı yönergelerini gözden geçirin.

  • Dizine alınan görünümlerin değerini değerlendirin. Örnek kilitlenmemizin yeniden oluşmasını önlemeye yönelik bir diğer seçenek de dizine alınmış görünümü bırakmaktır SalesLT.vProductAndDescription . Bu dizinlenmiş görünüm kullanılmıyorsa, bu durum zaman içinde dizinlenmiş görünümü koruma yükünü azaltır.

  • Anlık görüntü yalıtımını kullanın. Bazı durumlarda, kilitlenmeye dahil olan işlemlerden biri veya daha fazlası için işlem yalıtım düzeyini anlık görüntü olarak ayarlamak engellemeyi ve kilitlenmelerin yeniden oluşmasını engelleyebilir.

    Bu teknik büyük olasılıkla veritabanında kaydedilmiş okuma anlık görüntüsü devre dışı bırakıldığında SELECT deyimlerinde kullanıldığında başarılı olacaktır. Okunan kaydedilmiş anlık görüntü devre dışı bırakıldığında, kaydedilmiş okuma yalıtım düzeyini kullanan SELECT sorguları paylaşılan (S) kilitler gerektirir. Bu işlemlerde anlık görüntü yalıtımının kullanılması, engellemeyi ve kilitlenmeleri önleyebilecek paylaşılan kilit ihtiyacını ortadan kaldırır.

    Okuma işlemi yapılan anlık görüntü yalıtımının etkinleştirildiği veritabanlarında SELECT sorguları paylaşılan (S) kilitleri gerektirmez, bu nedenle verileri değiştiren işlemler arasında kilitlenmeler oluşma olasılığı daha yüksektir. Verileri değiştiren birden çok işlem arasında kilitlenmeler oluştuğu durumlarda, anlık görüntü yalıtımı kilitlenme yerine güncelleştirme çakışması ile sonuçlanabilir. Bu benzer şekilde işlemlerden birinin işlemini yeniden denemesini gerektirir.

  • Sorgu Deposu ile bir planı zorlama. Kilitlenmedeki sorgulardan birinin birden çok yürütme planı olduğunu ve kilitlenmenin yalnızca belirli bir plan kullanıldığında gerçekleştiğini fark edebilirsiniz. Sorgu Deposu'nda bir planı zorlayarak kilitlenmenin yeniden oluşmasını önleyebilirsiniz.

  • Transact-SQL'i değiştirin. Kilitlenmenin yeniden oluşmasını önlemek için Transact-SQL'i değiştirmeniz gerekebilir. Transact-SQL'i değiştirme işlemi dikkatle yapılmalı ve değişiklikler eşzamanlı olarak çalıştırıldığında verilerin doğru olduğundan emin olmak için sıkı bir şekilde test edilmelidir. Transact-SQL'i yeniden yazarken şunları göz önünde bulundurun:

    • İşlemlerdeki deyimleri, nesnelere aynı sırayla erişebilecek şekilde sıralama.
    • Mümkün olduğunda işlemleri daha küçük işlemlere ayırma.
    • Performansı iyileştirmek için gerekirse sorgu ipuçlarını kullanma. Sorgu Deposu'nu kullanarak uygulama kodunu değiştirmeden ipuçları uygulayabilirsiniz.

kilitlenmeleri en aza indirmenin diğer yollarını İşlem kilitleme ve satır sürümü oluşturma kılavuzunda bulabilirsiniz.

Not

Bazı durumlarda, oturumlardan birinin yeniden denemeden başarıyla tamamlanması önemliyse veya kilitlenmeye dahil olan sorgulardan biri kritik değilse ve her zaman kurban olarak seçilmesi gerekiyorsa, kilitlenmeye dahil olan bir veya daha fazla oturumun kilitlenme önceliğini ayarlamak isteyebilirsiniz. Bu, kilitlenmenin yeniden oluşmasını engellemese de, gelecekteki kilitlenmelerin etkisini azaltabilir.

XEvents oturumlarını bırakma

Uzun süreler boyunca kritik veritabanlarında çalışan kilitlenme bilgilerini toplayan bir XEvents oturumu bırakmak isteyebilirsiniz. Bir olay dosyası hedefi kullanırsanız, birden çok kilitlenme oluşursa bunun büyük dosyalara neden olabileceğini unutmayın. Şu anda yazılmakta olan dosya dışında etkin bir izleme için Blob dosyalarını Azure Depolama'dan silebilirsiniz.

XEvents oturumunu kaldırmak istediğinizde, seçilen hedef türü ne olursa olsun Transact-SQL bırakma işlemi aynı oturumdur.

XEvents oturumunu kaldırmak için aşağıdaki Transact-SQL'i çalıştırın. Kodu çalıştırmadan önce oturumun adını uygun değerle değiştirin.

ALTER EVENT SESSION [deadlocks] ON DATABASE
    STATE = STOP;
GO

DROP EVENT SESSION [deadlocks] ON DATABASE;
GO

Azure Depolama Gezgini'ni kullanma

Azure Depolama Gezgini, Azure Depolama'daki bloblarda depolanan olay dosyası hedefleriyle çalışmayı basitleştiren tek başına bir uygulamadır. Depolama Gezgini kullanarak şunları yapabilirsiniz:

İndir Azure Depolama Gezgini..

Sonraki adımlar

Azure SQL Veritabanında performans hakkında daha fazla bilgi edinin: