SELECT deyimlerinde NOLOCK ipucunun etkisi


199

Asıl soru şu:

Ben kirli okumalar umurumda değilse, bir SELECT deyimi ile (NOLOCK) ipucu ekleyerek performansını etkileyecektir:

  1. geçerli SELECT deyimi
  2. verilen tabloya göre yapılan diğer işlemler

Misal:

Select * 
from aTable with (NOLOCK)

3
Bu SO ve DBA cevapları gerçekte ne olduğu konusunda biraz daha açıktır.
20'de Trisped

Yanıtlar:


289

1) Evet , ile yapılan bir seçim NOLOCKnormal seçimden daha hızlı tamamlanır.

2) Evet , ile yapılan bir seçim NOLOCK, etkilenen tablodaki diğer sorguların normal seçimden daha hızlı tamamlanmasını sağlar.

Neden böyle olsun ki?

NOLOCKtipik olarak (DB motorunuza bağlı olarak) bana verilerinizi vermek anlamına gelir ve ben hangi durumda olduğunu umurumda değil ve sizden okurken onu hala tutmak rahatsız etmeyin. Hepsi aynı anda daha hızlı, daha az kaynak yoğun ve çok tehlikelidir.

Sistem açısından kritik öneme sahip herhangi bir şeyden veya bir NOLOCKokumadan kaynaklanan veriler kullanılarak mutlak doğruluk gerektiğinde hiçbir zaman güncelleme yapmamanız veya uyarılmamanız gerekir . Bu verilerin, sorgunun çalışması sırasında silinmiş veya henüz sonlandırılmamış diğer oturumlarda silinmiş satırları içermesi kesinlikle mümkündür. Bu verilerin kısmen güncellenmiş satırları içermesi mümkündür. Bu verilerin yabancı anahtar kısıtlamalarını ihlal eden kayıtlar içermesi mümkündür. Bu verilerin tabloya eklenmiş ancak henüz işlenmemiş satırları içermemesi mümkündür.

Verilerin durumunun ne olduğunu bilmenin hiçbir yolu yok.

Satır Sayısı veya bazı hata paylarının kabul edilebilir olduğu diğer özet veriler gibi şeyler almaya çalışıyorsanız, NOLOCKbu sorgular için performansı artırmak ve veritabanı performansını olumsuz etkilemekten kaçınmanın iyi bir yoludur.

İpucunu her zaman NOLOCKbüyük bir dikkatle kullanın ve döndürdüğü tüm verileri şüpheyle ele alın.


Teşekkürler. Bu varsaydığım şeydi ama bir meslektaşım tarafından bu konuda sorgulandı ve ilk araştırmam bana kendimi sorguladı. SQLServer 2005 belgeleri, NOLOCK ile tüm seçme ifadeler için varsayılan kilitleme şeması olduğunu söylüyor! Tahminimce ipuçlarım gereksiz olur ...
Bob Probst

2
... 2005 ve hiçbir etkisi yok. Şu anda 2000'i çalıştırıyoruz (satıcımız sayesinde) ve belgelerde benzer bir açıklama yok.
Bob Probst

4
Arkadaşınızın belgeleri okuması gerekiyor. Tablo İpucu (Transact-SQL) msdn.microsoft.com/tr-tr/library/ms187373(SQL.90).aspx
Pittsburgh DBA

9
Yan not: eğer bu doğru olsaydı, mutlak kaos olurdu.
Pittsburgh DBA

1
1 ve 2 numaralı noktaların 1) ile sınırlandırılması gerekir "... masada ekleme / güncelleme / silme işlemi beklemede ." ve 2) "... sorguların eklenmesine / güncellenmesine / silinmesine izin verir ...". (Kişisel tercih) "daha hızlı" örneklerini "daha erken" olarak değiştirirdim, çünkü fark başka bir işlemin tamamlanmasını bekliyor.
16:20

61

NOLOCK, paylaşılan kilitlerin bulunmaması nedeniyle çoğu SELECT deyimini daha hızlı hale getirir. Ayrıca, kilitlerin düzenlenmemesi, yazarların SELECT tarafından engellenmeyeceği anlamına gelir.

NOLOCK işlevsel olarak READ UNCOMMITTED izolasyon seviyesine eşdeğerdir. Temel fark, NOLOCK'u bazı tablolarda kullanabilmenizdir, ancak diğerlerini seçmemenizdir. Karmaşık bir sorgudaki tüm tablolarda NOLOCK kullanmayı planlıyorsanız, her tabloya ipucu uygulamanız gerekmediğinden SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED'i kullanmak daha kolaydır.

İşte emrinizdeki tüm izolasyon seviyeleri ve tablo ipuçları hakkında bilgi.

İŞLEM İZOLASYON DÜZEYİNİ AYARLA

Tablo İpucu (Transact-SQL)


2
Katılıyorum, ama tamamen değil; NO LOCK / READ UNCOMMITTED ipucunun aslında sorgunun hızını iyileştirmediğine dikkat etmek önemlidir, ancak daha fazlası, önceki sorguların tamamlanmasını beklemek zorunda olmadığı için daha hızlı görünmesini sağlar. Yani gerçekten, sorgu daha hızlı SEEMS, daha hızlı IS (sanırım).
Möoz

1
@BorhanMooz Eh, kilit yöneticisinden kilit istememek zorunda kalmadan tasarruf var. Bekleyen başka sorgu olmasa bile, bunun bir maliyeti ve bir bellek yükü vardır.
Pittsburgh DBA

1
Bunu bazı çalışma arkadaşlarımla tartışıyordum. Anladığım kadarıyla, bir WITH (NOLOCK) ipucu kullanan bir sorgu hala bir Şema Paylaşımlı kilit elde gerektirir ( mssqltips.com/sqlservertip/2470/… ).
Möoz

1
Evet, ancak sayfalarda veya uzantılarda binlerce paylaşılan kilit değil. Şema kilidi BİN değil, BİR kilittir. Bilgiçlikçi olmak istiyorsak, bunu tartışmaya devam edebiliriz, ancak evet, minimum miktarda kilit yük olacak. Tasarruf önemlidir. Bu konuda matematik yapın: msdn.microsoft.com/en-us/library/aa337559(v=sql.100).aspx
Pittsburgh DBA


6

Daha hızlı olacak çünkü kilitleri beklemek zorunda değil


Ne kadar hızlı? Herhangi bir hız iyileştirme numarası verebilir misiniz?
Eugeniu Torica

5
"Ne kadar" değeri, verilerinizle özel olarak ne yaptığınıza ve genellikle kilit alımını beklemek zorunda olduğunuz süreye bağlıdır.
StingyJack

Tek doğru kriter, kendi oluşturup çalıştıracağınız ölçüttür. Herkesin söylediği şey "çek postada" kadar iyidir. Kendi kriterlerimi çalıştırarak birçok efsane ve varsayımı birçok kez yanlış kanıtladım.
TravisO

^ @TravisO - tamamen doğrudur. NOLOCK'u birkaç kez daha yavaş çalıştırdım. Tam olarak emin niçin ama giderme ve olumsuz (over) istediğiniz sevmediği zaman üretimini etkilediğini kullanıyorum Değil
StingyJack

2
  • Cevap edilir Evet her bir işlem tamamlanmış diğerleri için beklemek gerekmez, çünkü sorgu, tek seferde birden fazla kez çalıştırılırsa. Ancak, sorgu tek başına çalıştırılırsa, yanıt Hayır olur.

  • Evet . WITH (NOLOCK) 'un dikkatli kullanılmasının veritabanınızı genel olarak hızlandırması ihtimali yüksektir. Bu, diğer işlemlerin bu SELECT ifadesinin bitmesini beklemek zorunda kalmayacağı, ancak diğer işlemlerin artık işlem sürelerini yeni bir işlemle paylaştıkları için yavaşlayacağı anlamına gelir.

Yalnızca kullanmaya dikkat edinWITH (NOLOCK)Kümelenmiş dizini olan tablolarda SELECT deyimlerinde .

WITH (NOLOCK) genellikle veritabanı okuma işlemlerini hızlandırmak için sihirli bir yol olarak kullanılır.

Sonuç kümesi henüz işlenmemiş, daha sonra geri alınan satırlar içerebilir.

Kümelenmemiş bir dizine sahip bir tabloya WITH (NOLOCK) uygulanırsa, satır verileri sonuç tablosuna aktarılırken satır dizinleri diğer işlemler tarafından değiştirilebilir. Bu, sonuç kümesinin satır eksik olabileceği veya aynı satırı birden çok kez görüntüleyebileceği anlamına gelir.

COMMITTED READITED, birden çok kullanıcının aynı hücreyi aynı anda değiştirdiği tek bir sütunda verilerin bozulduğu ek bir sorun ekler.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.