Tablo ipuçları (Transact-SQL)
Tablo ipuçları, veri işleme dili (DML) deyimi sırasında sorgu iyileştiricisinin varsayılan davranışını geçersiz kılmak için kullanılır. Bir kilitleme yöntemi, bir veya daha fazla dizin, tablo taraması veya dizin arama gibi bir sorgu işleme işlemi veya diğer seçenekler belirtebilirsiniz. Tablo ipuçları DML deyiminin FROM
yan tümcesinde belirtilir ve yalnızca bu yan tümcede başvuruda bulunan tabloyu veya görünümü etkiler.
Dikkat
SQL Server sorgu iyileştiricisi genellikle sorgu için en iyi yürütme planını seçtiğinden, ipuçlarının yalnızca deneyimli geliştiriciler ve veritabanı yöneticileri tarafından son çare olarak kullanılmasını öneririz.
Şunlar için geçerlidir:
- DELETE
- insert
- SELECT
- update
- MERGE
Transact-SQL söz dizimi kuralları
Sözdizimi
WITH ( <table_hint> [ [ , ] ...n ] )
<table_hint> ::=
{ NOEXPAND
| INDEX ( <index_value> [ , ...n ] ) | INDEX = ( <index_value> )
| FORCESEEK [ ( <index_value> ( <index_column_name> [ , ... ] ) ) ]
| FORCESCAN
| HOLDLOCK
| NOLOCK
| NOWAIT
| PAGLOCK
| READCOMMITTED
| READCOMMITTEDLOCK
| READPAST
| READUNCOMMITTED
| REPEATABLEREAD
| ROWLOCK
| SERIALIZABLE
| SNAPSHOT
| SPATIAL_WINDOW_MAX_CELLS = <integer_value>
| TABLOCK
| TABLOCKX
| UPDLOCK
| XLOCK
}
<table_hint_limited> ::=
{
KEEPIDENTITY
| KEEPDEFAULTS
| HOLDLOCK
| IGNORE_CONSTRAINTS
| IGNORE_TRIGGERS
| NOLOCK
| NOWAIT
| PAGLOCK
| READCOMMITTED
| READCOMMITTEDLOCK
| READPAST
| REPEATABLEREAD
| ROWLOCK
| SERIALIZABLE
| SNAPSHOT
| TABLOCK
| TABLOCKX
| UPDLOCK
| XLOCK
}
Bağımsız değişken
WITH ( <table_hint> ) [ [ , ] ...n ]
Bazı özel durumlarda, tablo ipuçları yalnızca ipuçları WITH
anahtar sözcüğüyle belirtildiğinde FROM
yan tümcesinde desteklenir. Tablo ipuçları da parantez içinde belirtilmelidir.
Önemli
WITH
anahtar sözcüğünü kullanım dışı bırakma özelliğidir: Bu özellik SQL Server'ın gelecekteki bir sürümünde kaldırılacaktır. Bu özelliği yeni geliştirme çalışmalarında kullanmaktan kaçının ve şu anda bu özelliği kullanan uygulamaları değiştirmeyi planlayın.
aşağıdaki tablo ipuçlarına WITH
anahtar sözcüğüyle ve anahtar sözcüğü olmadan izin verilir: NOLOCK
, READUNCOMMITTED
, UPDLOCK
, REPEATABLEREAD
, SERIALIZABLE
, READCOMMITTED
, TABLOCK
, TABLOCKX
, PAGLOCK
, ROWLOCK
, NOWAIT
, READPAST
, XLOCK
, SNAPSHOT
ve NOEXPAND
. Bu tablo ipuçları WITH
anahtar sözcüğü olmadan belirtildiğinde, ipuçları tek başına belirtilmelidir. Mesela:
FROM t (TABLOCK)
İpucu başka bir seçenekle belirtildiğinde, ipucu WITH
anahtar sözcüğüyle belirtilmelidir:
FROM t WITH (TABLOCK, INDEX(myindex))
Tablo ipuçları arasında virgül kullanmanızı öneririz.
Önemli
İpuçlarını virgül yerine boşluklarla ayırmak kullanımdan kaldırılmış bir özelliktir: Bu özellik, SQL Server'ın gelecekteki bir sürümünde kaldırılacaktır. Bu özelliği yeni geliştirme çalışmalarında kullanmaktan kaçının ve şu anda bu özelliği kullanan uygulamaları değiştirmeyi planlayın.
NOEXPAND
Sorgu iyileştiricisi sorguyu işlediğinde dizine alınan görünümlerin temel tablolara erişecek şekilde genişletildiğini belirtir. Sorgu iyileştiricisi görünümü kümelenmiş dizine sahip bir tablo gibi değerlendirir.
NOEXPAND
yalnızca dizinlenmiş görünümler için geçerlidir. Daha fazla bilgi için bkz. NOEXPANDkullanma
İNDİS ( <index_value> [ , ...n ] ) | İNDİS = ( <index_value> )
INDEX()
söz dizimi, sorgu iyileştiricisi deyimini işlerken kullanılacak bir veya daha fazla dizinin adlarını veya kimliklerini belirtir. Alternatif INDEX =
söz dizimi tek bir dizin değeri belirtir. Tablo başına yalnızca bir dizin ipucu belirtilebilir.
Kümelenmiş dizin varsa, INDEX(0)
kümelenmiş dizin taramasına zorlar ve INDEX(1)
kümelenmiş dizin taramasına veya aramaya zorlar. Kümelenmiş dizin yoksa, INDEX(0)
tablo taramasına zorlar ve INDEX(1)
hata olarak yorumlanır.
Tek bir ipucu listesinde birden çok dizin kullanılıyorsa, yinelenenler yoksayılır ve listelenen dizinlerin geri kalanı tablonun satırlarını almak için kullanılır. Dizin ipucundaki dizinlerin sırası önemlidir. Birden çok dizin ipucu dizin ANDing'i de zorunlu kılır ve sorgu iyileştiricisi erişilen her dizinde mümkün olduğunca çok koşul uygular. İpucu oluşturulmuş dizin koleksiyonu sorgu tarafından başvuruda bulunılan tüm sütunları içermiyorsa, SQL Server Veritabanı Altyapısı tüm dizinlenmiş sütunları aldıktan sonra kalan sütunları almak için bir getirme gerçekleştirilir.
Not
Yıldız birleştirmesinde olgu tablosunda birden çok dizine başvuran bir dizin ipucu kullanıldığında, iyileştirici dizin ipucunu yoksayar ve bir uyarı iletisi döndürür. Ayrıca, dizin ipucu belirtilen bir tablo için dizin ORing'e izin verilmez.
Tablo ipucundaki dizin sayısı üst sınırı, 250 kümelenmemiş dizindir.
KEEPIDENTITY
Yalnızca BULK
seçeneği OPENROWSETile kullanıldığında INSERT
deyiminde geçerlidir.
İçeri aktarılan veri dosyasındaki kimlik değerinin veya değerlerinin kimlik sütunu için kullanılacağını belirtir.
KEEPIDENTITY
belirtilmezse, bu sütunun kimlik değerleri doğrulanır ancak içeri aktarılmaz ve sorgu iyileştiricisi tablo oluşturma sırasında belirtilen tohum ve artım değerlerine göre otomatik olarak benzersiz değerler atar.
Önemli
Veri dosyası tablo veya görünümdeki kimlik sütunu için değerler içermiyorsa ve kimlik sütunu tablodaki son sütun değilse, kimlik sütununu atlamalısınız. Daha fazla bilgi için bkz. Veri alanını atlamak için biçim dosyası kullanma (SQL Server). Bir kimlik sütunu başarıyla atlanırsa, sorgu iyileştiricisi içeri aktarılan tablo satırlarına kimlik sütunu için otomatik olarak benzersiz değerler atar.
INSERT ... SELECT * FROM OPENROWSET(BULK...)
deyiminde bu ipucunu kullanan bir örnek için bkz. Verileri toplu içeri aktarırken kimlik değerlerini koruma (SQL Server).
Bir tablonun kimlik değerini denetleme hakkında bilgi için bkz. DBCC CHECKIDENT.
KEEPDEFAULTS
Yalnızca BULK
seçeneği OPENROWSETile kullanıldığında INSERT
deyiminde geçerlidir.
Veri kaydında sütun için değer olmadığında NULL
yerine, varsa tablo sütununun varsayılan değerinin eklenmesini belirtir.
FORCESEEK [ ( <index_value> ( <index_column_name> [ , ...n ] ) ) ]
Sorgu iyileştiricisinin tablo veya görünümdeki verilere erişim yolu olarak yalnızca dizin arama işlemini kullandığını belirtir.
Not
SQL Server 2008 R2 (10.50.x) Service Pack 1'den başlayarak dizin parametreleri de belirtilebilir. Bu durumda, sorgu iyileştiricisi en azından belirtilen dizin sütunlarını kullanarak belirtilen dizin üzerinden yalnızca dizin arama işlemlerini dikkate alır.
index_value
Dizin adı veya dizin kimliği değeri. Dizin kimliği 0 (yığın) belirtilemiyor. Dizin adını veya kimliğini döndürmek için
sys.indexes
katalog görünümünü sorgular.index_column_name
Arama işlemine eklenecek dizin sütununun adı. dizin parametreleriyle
FORCESEEK
belirtmek,INDEX
ipucuylaFORCESEEK
kullanmaya benzer. Ancak, hem aranacak dizini hem de arama işleminde dikkate alınacak dizin sütunlarını belirterek sorgu iyileştiricisi tarafından kullanılan erişim yolu üzerinde daha fazla denetim elde edebilirsiniz. İyileştirici gerekirse daha fazla sütun göz önünde bulundurabilir. Örneğin, kümelenmemiş bir dizin belirtilirse, iyileştirici belirtilen sütunlara ek olarak kümelenmiş dizin anahtarı sütunlarını kullanmayı seçebilir.
FORCESEEK
ipucu aşağıdaki yollarla belirtilebilir.
Sözdizimi | Örnek | Açıklama |
---|---|---|
Dizin veya INDEX ipucu olmadan |
FROM dbo.MyTable WITH (FORCESEEK) |
Sorgu iyileştirici, tabloya erişmek veya ilgili dizinler aracılığıyla görüntülemek için yalnızca dizin arama işlemlerini dikkate alır. |
INDEX ipucuyla birleştirilmiş |
FROM dbo.MyTable WITH (FORCESEEK, INDEX (MyIndex)) |
Sorgu iyileştiricisi yalnızca belirtilen dizin aracılığıyla tabloya veya görünüme erişmek için dizin arama işlemlerini dikkate alır. |
Dizin ve dizin sütunları belirtilerek parametreleştirilmiş | FROM dbo.MyTable WITH (FORCESEEK (MyIndex (col1, col2, col3))) |
Sorgu iyileştiricisi, en azından belirtilen dizin sütunlarını kullanarak tabloya veya görünüme erişmek için yalnızca dizin arama işlemlerini dikkate alır. |
FORCESEEK
ipucunu kullanırken (dizin parametreleriyle veya olmadan), aşağıdaki yönergeleri göz önünde bulundurun:
- İpucu, tablo ipucu veya sorgu ipucu olarak belirtilebilir. Sorgu ipuçları hakkında daha fazla bilgi için bkz.
Sorgu ipuçları (Transact-SQL) . - dizinli görünüme
FORCESEEK
uygulamak içinNOEXPAND
ipucunun da belirtilmesi gerekir. - İpucu tablo veya görünüm başına en fazla bir kez uygulanabilir.
- İpucu uzak bir veri kaynağı için belirtilemiyor.
FORCESEEK
bir dizin ipucuyla belirtildiğinde hata 7377 döndürülür veFORCESEEK
dizin ipucu olmadan kullanıldığında 8180 hatası döndürülür. -
FORCESEEK
plan bulunamazsa 8622 hatası döndürülür.
dizin parametreleriyle FORCESEEK
belirtildiğinde, aşağıdaki yönergeler ve kısıtlamalar geçerlidir:
- İpucu,
INSERT
,UPDATE
veyaDELETE
deyiminin hedefi olan bir tablo için belirtilemiyor. - İpucu, bir
INDEX
ipucu veya başka birFORCESEEK
ipucu ile birlikte belirtilemiyor. - En az bir sütun belirtilmeli ve en baştaki anahtar sütunu olmalıdır.
- Ek dizin sütunları belirtilebilir, ancak anahtar sütunlar atlanamaz. Örneğin, belirtilen dizin ,
b
vec
a
anahtar sütunlarını içeriyorsa geçerli söz dizimiFORCESEEK (MyIndex (a))
veFORCESEEK (MyIndex (a, b)
içerir. Geçersiz söz dizimiFORCESEEK (MyIndex (c))
veFORCESEEK (MyIndex (a, c)
içerir. - İpucunda belirtilen sütun adlarının sırası, başvuruda bulunan dizindeki sütunların sırasıyla eşleşmelidir.
- Dizin anahtarı tanımında olmayan sütunlar belirtilemiyor. Örneğin, kümelenmemiş bir dizinde yalnızca tanımlı dizin anahtarı sütunları belirtilebilir. Dizine otomatik olarak eklenen kümelenmiş anahtar sütunları belirtilemiyor, ancak iyileştirici tarafından kullanılabilir.
- xVelocity bellek için iyileştirilmiş columnstore dizini dizin parametresi olarak belirtilemiyor. Hata 366 döndürülür.
- Dizin tanımını değiştirmek (örneğin, sütunları ekleyerek veya kaldırarak) bu dizine başvuran sorgularda değişiklik yapılmasını gerektirebilir.
- İpucu, iyileştiricinin tablodaki uzamsal veya XML dizinlerini dikkate almalarını önler.
- İpucu,
FORCESCAN
ipucuyla birlikte belirtilemiyor. - Bölümlenmiş dizinler için SQL Server tarafından örtük olarak eklenen bölümleme sütunu
FORCESEEK
ipucunda belirtilemiyor.
Dikkat
parametrelerle FORCESEEK
belirtmek, iyileştirici tarafından parametre olmadan FORCESEEK
belirtirken dikkate alınabilecek plan sayısını sınırlar. Bu, daha fazla durumda bir Plan cannot be generated
hatası oluşmasına neden olabilir.
FORCESCAN
için geçerlidir: SQL Server 2008 R2 (10.50.x) Service Pack 1 ve sonraki sürümleri
Sorgu iyileştiricisinin başvuruda bulunan tablo veya görünüme erişim yolu olarak yalnızca bir dizin tarama işlemi kullandığını belirtir.
FORCESCAN
ipucu, iyileştiricinin etkilenen satır sayısını hafife aldığı ve tarama işlemi yerine bir arama işlemi seçtiği sorgular için yararlı olabilir. Bu durum oluştuğunda, işlem için verilen bellek miktarı çok küçük olur ve sorgu performansı etkilenir.
FORCESCAN
INDEX
ipucuyla veya ipucu olmadan belirtilebilir. Bir dizin ipucu (INDEX = index_name, FORCESCAN
) ile birleştirildiğinde, sorgu iyileştiricisi başvuruda bulunan tabloya erişirken yalnızca belirtilen dizin üzerinden erişim yollarını taramayı dikkate alır.
FORCESCAN
, temel tabloda tablo tarama işlemini zorlamak için dizin ipucu INDEX(0)
belirtilebilir.
Bölümlenmiş tablolar ve dizinler için, sorgu koşulu değerlendirmesi aracılığıyla bölümler ortadan kaldırıldıktan sonra FORCESCAN
uygulanır. Bu, taramanın tablonun tamamına değil yalnızca kalan bölümlere uygulandığı anlamına gelir.
FORCESCAN
ipucu aşağıdaki kısıtlamalara sahiptir:
- İpucu,
INSERT
,UPDATE
veyaDELETE
deyiminin hedefi olan bir tablo için belirtilemiyor. - İpucu birden fazla dizin ipucuyla kullanılamaz.
- İpucu, sorgu iyileştiricisinin tablodaki uzamsal veya XML dizinlerini dikkate almalarını engeller.
- İpucu uzak bir veri kaynağı için belirtilemiyor.
- İpucu,
FORCESEEK
ipucuyla birlikte belirtilemiyor.
HOLDLOCK
SERIALIZABLE
eşdeğerdir. Daha fazla bilgi için bu makalenin devamında SERIALIZABLE konusuna bakın.
HOLDLOCK
yalnızca belirtilen tablo veya görünüm için ve yalnızca içinde kullanıldığı deyim tarafından tanımlanan işlem süresi için geçerlidir.
HOLDLOCK
, FOR BROWSE
seçeneğini içeren bir SELECT deyiminde kullanılamaz.
IGNORE_CONSTRAINTS
Yalnızca BULK
seçeneği OPENROWSETile kullanıldığında INSERT
deyiminde geçerlidir.
Toplu içeri aktarma işleminin tablodaki kısıtlamaları yoksaydığını belirtir. Varsayılan olarak, IGNORE_CONSTRAINTS
belirtildiğinde, INSERT
hedef tablodaki bu kısıtlamaları yoksaymalıdır.
UNIQUE
, PRIMARY KEY
veya NOT NULL
kısıtlamalarını devre dışı bırakamazsınız.
Giriş verileri kısıtlamaları ihlal eden satırlar içeriyorsa CHECK
ve FOREIGN KEY
kısıtlamalarını devre dışı bırakmak isteyebilirsiniz.
CHECK
ve FOREIGN KEY
kısıtlamalarını devre dışı bırakarak verileri içeri aktarabilir ve verileri temizlemek için Transact-SQL deyimlerini kullanabilirsiniz.
Ancak, CHECK
ve FOREIGN KEY
kısıtlamaları yoksayıldığında, tablodaki yoksayılan her kısıtlama, işlemden sonra sys.check_constraints veya sys.foreign_keys katalog görünümünde is_not_trusted
olarak işaretlenir. Bir noktada, tablonun tamamında kısıtlamaları denetlemeniz gerekir. Toplu içeri aktarma işleminden önce tablo boş değilse, kısıtlamayı yeniden doğrulamanın maliyeti artımlı verilere CHECK
ve FOREIGN KEY
kısıtlamaları uygulama maliyetini aşabilir.
IGNORE_TRIGGERS
Yalnızca BULK
seçeneği OPENROWSETile kullanıldığında INSERT
deyiminde geçerlidir.
Tabloda tanımlanan tüm tetikleyicilerin toplu içeri aktarma işlemi tarafından yoksayılacağını belirtir. Varsayılan olarak, INSERT
tetikleyicileri uygular.
IGNORE_TRIGGERS
yalnızca uygulamanız herhangi bir tetikleyiciye bağımlı değilse kullanın ve performansı en üst düzeye çıkarmak önemlidir.
NOLOCK
READUNCOMMITTED
eşdeğerdir. Daha fazla bilgi için bu makalenin devamında yer alan READUNCOMMITTED
Not
UPDATE
veya DELETE
deyimleri için: Bu özellik SQL Server'ın gelecekteki bir sürümünde kaldırılacaktır. Bu özelliği yeni geliştirme çalışmalarında kullanmaktan kaçının ve şu anda bu özelliği kullanan uygulamaları değiştirmeyi planlayın.
NOWAIT
Veritabanı Altyapısı'na, tabloda bir kilitle karşılaşılır karşılaşılmaz bir ileti döndürmesini belirtir.
NOWAIT
, belirli bir tablo için SET LOCK_TIMEOUT 0
belirtmeye eşdeğerdir.
TABLOCK
ipucu da eklendiğinde NOWAIT
ipucu çalışmaz.
TABLOCK
ipucunu kullanırken beklemeden sorguyu sonlandırmak için sorgunun başına SET LOCK_TIMEOUT 0;
ekleyin.
PAGLOCK
Tek tek kilitlerin satırlarda veya anahtarlarda normalde alındığı veya tek bir tablo kilidinin normalde alındığı sayfa kilitlerini alır. Varsayılan olarak, işlem için uygun kilit modunu kullanır.
SNAPSHOT
yalıtım düzeyinde çalışan işlemlerde belirtildiğinde, PAGLOCK
UPDLOCK
ve HOLDLOCK
gibi kilit gerektiren diğer tablo ipuçlarıyla birleştirilmediği sürece sayfa kilitleri alınmaz.
READCOMMITTED
Okuma işlemlerinin, kilitleme veya satır sürümü oluşturma kullanarak READ COMMITTED
yalıtım düzeyi kurallarıyla uyumlu olduğunu belirtir. veritabanı seçeneği READ_COMMITTED_SNAPSHOT
OFF
ise, veri okundukça Veritabanı Altyapısı paylaşılan kilitleri alır ve okuma işlemi tamamlandığında bu kilitleri serbest bırakır. veritabanı seçeneği READ_COMMITTED_SNAPSHOT
ON
ise, Veritabanı Altyapısı kilitleri almaz ve satır sürümü oluşturma kullanır. Yalıtım düzeyleri hakkında daha fazla bilgi için bkz. SET TRANSACTION ISOLATION LEVEL.
Not
UPDATE
veya DELETE
deyimleri için: Bu özellik SQL Server'ın gelecekteki bir sürümünde kaldırılacaktır. Bu özelliği yeni geliştirme çalışmalarında kullanmaktan kaçının ve şu anda bu özelliği kullanan uygulamaları değiştirmeyi planlayın.
READCOMMITTEDLOCK
Okuma işlemlerinin kilitleme kullanarak READ COMMITTED
yalıtım düzeyine yönelik kurallarla uyumlu olduğunu belirtir. Veritabanı Altyapısı, veriler okundukça paylaşılan kilitleri alır ve READ_COMMITTED_SNAPSHOT
veritabanı seçeneğinin ayarından bağımsız olarak okuma işlemi tamamlandığında bu kilitleri serbest bırakır. Yalıtım düzeyleri hakkında daha fazla bilgi için bkz. SET TRANSACTION ISOLATION LEVEL. Bu ipucu bir INSERT
deyiminin hedef tablosunda belirtilemiyor; hata 4140 döndürülür.
READPAST
Veritabanı Altyapısı'nın diğer işlemler tarafından kilitlenen satırları okumadığını belirtir.
READPAST
belirtildiğinde satır düzeyi kilitler atlanır, ancak sayfa düzeyi kilitler atlanmaz. Başka bir ifadeyle, Veritabanı Altyapısı kilitler serbest bırakılana kadar geçerli işlemi engellemek yerine satırları atlar. Örneğin, tablo T1
1, 2, 3, 4, 5 değerlerine sahip tek bir tamsayı sütunu içerdiğini varsayalım. A işlemi 3 değerini 8 olarak değiştirirse ancak henüz işlenmediyse, SELECT * FROM T1 (READPAST)
1, 2, 4, 5 değerlerini verir.
READPAST
öncelikle SQL Server tablosu kullanan bir iş kuyruğu uygularken kilitleme çekişmesini azaltmak için kullanılır.
READPAST
kullanan bir kuyruk okuyucu, diğer işlemler tarafından kilitlenen geçmiş kuyruk girişlerini, diğer işlemlerin kilitlerini serbest bırakmasını beklemek zorunda kalmadan bir sonraki kullanılabilir kuyruk girdisine atlar.
READPAST
, bir UPDATE
veya DELETE
deyiminde başvuruda bulunılan herhangi bir tablo ve FROM
yan tümcesinde başvurulabilecek herhangi bir tablo için belirtilebilir. bir UPDATE
deyiminde belirtildiğinde, READPAST
yalnızca hangi kayıtların belirtildiğine bakılmaksızın güncelleştirilecek kayıtları belirlemek için veriler okunurken uygulanır.
READPAST
INSERT
deyiminin INTO
yan tümcesindeki tablolar için belirtilemiyor.
READPAST
kullanan güncelleştirme veya silme işlemleri, yabancı anahtarları veya dizine alınan görünümleri okurken veya ikincil dizinleri değiştirirken engelleyebilir.
READPAST
yalnızca READ COMMITTED
veya REPEATABLE READ
yalıtım düzeylerinde çalışan işlemlerde belirtilebilir.
SNAPSHOT
yalıtım düzeyinde çalışan işlemlerde belirtildiğinde, READPAST
UPDLOCK
ve HOLDLOCK
gibi kilit gerektiren diğer tablo ipuçlarıyla birleştirilmelidir.
READ_COMMITTED_SNAPSHOT
veritabanı seçeneği ON
olarak ayarlandığında ve aşağıdaki koşullardan biri doğru olduğunda READPAST
tablo ipucu belirtilemiyor:
- Oturumun işlem yalıtım düzeyi
READ COMMITTED
. -
READCOMMITTED
tablo ipucu da sorguda belirtilir.
Bu durumlarda READPAST
ipucunu belirtmek için varsa READCOMMITTED
tablo ipucunu kaldırın ve sorguya READCOMMITTEDLOCK
tablo ipucunu ekleyin.
READUNCOMMITTED
Kirli okumalara izin verildiğini belirtir. Diğer işlemlerin geçerli işlem tarafından okunan verileri değiştirmesini önlemek için paylaşılan kilitler verilmez ve diğer işlemler tarafından ayarlanan özel kullanım kilitleri geçerli işlemin kilitli verileri okumasını engellemez. Kirli okumalara izin vermek daha yüksek eşzamanlılığa neden olabilir, ancak daha sonra diğer işlemler tarafından geri alınan veri değişikliklerinin okunması karşılığında. Bu işlem için hatalar oluşturabilir, kullanıcılara hiç işlenmeyen verileri sunabilir veya kullanıcıların kayıtları iki kez görmesine neden olabilir (ya da hiç değil).
READUNCOMMITTED
ve NOLOCK
ipuçları yalnızca veri kilitleri için geçerlidir.
READUNCOMMITTED
ve NOLOCK
ipuçları içeren sorgular da dahil olmak üzere tüm sorgular, derleme ve yürütme sırasında Sch-S (şema kararlılığı) kilitleri alır. Bu nedenle, eşzamanlı bir işlem tabloda bir Sch-M (şema değişikliği) kilidi tuttuğunda sorgular engellenir. Örneğin, veri tanımı dili (DDL) işlemi tablonun şema bilgilerini değiştirmeden önce bir Sch-M kilidi alır.
READUNCOMMITTED
veya NOLOCK
ipuçlarıyla çalışan sorgular da dahil olmak üzere tüm eşzamanlı sorgular, Sch-S kilidi alınmaya çalışılırken engellenir. Buna karşılık, Sch-S kilidi tutan bir sorgu, Sch-M kilidi almaya çalışan eşzamanlı işlemi engeller.
ekleme, güncelleştirme veya silme işlemleriyle değiştirilen tablolar için READUNCOMMITTED
ve NOLOCK
belirtilemez. SQL Server sorgu iyileştiricisi, UPDATE
veya DELETE
deyiminin hedef tablosuna uygulanan FROM
yan tümcesindeki READUNCOMMITTED
ve NOLOCK
ipuçlarını yoksayar.
Not
UPDATE
veya DELETE
deyiminin hedef tablosuna uygulanan FROM
yan tümcesindeki READUNCOMMITTED
ve NOLOCK
ipuçlarının kullanımı desteği, SQL Server'ın gelecekteki bir sürümünde kaldırılacaktır. Yeni geliştirme çalışmalarında bu bağlamda bu ipuçlarını kullanmaktan kaçının ve bunları kullanmakta olan uygulamaları değiştirmeyi planlayın.
Aşağıdaki seçeneklerden birini kullanarak işlemleri kaydedilmemiş veri değişikliklerinin kirli okumalarına karşı korurken kilitlenme çekişmesi en aza indirgenebilir:
-
READ_COMMITTED_SNAPSHOT
veritabanı seçeneğininON
ayarlandığıREAD COMMITTED
yalıtım düzeyi. -
SNAPSHOT
yalıtım düzeyi.
Yalıtım düzeyleri hakkında daha fazla bilgi için bkz. SET TRANSACTION ISOLATION LEVEL.
Not
READUNCOMMITTED
belirtildiğinde hata iletisi 601 alırsanız, kilitlenme hatası (hata iletisi 1205) gibi düzeltin ve deyiminizi yeniden deneyin.
REPEATABLEREAD
Taramanın, REPEATABLE READ
yalıtım düzeyinde çalışan bir işlemle aynı kilitleme semantiğiyle gerçekleştirildiğini belirtir. Yalıtım düzeyleri hakkında daha fazla bilgi için bkz. SET TRANSACTION ISOLATION LEVEL.
ROWLOCK
Sayfa veya tablo kilitleri normalde alındığında satır kilitlerinin alındığını belirtir.
SNAPSHOT
yalıtım düzeyinde çalışan işlemlerde belirtildiğinde, ROWLOCK
UPDLOCK
ve HOLDLOCK
gibi kilit gerektiren diğer tablo ipuçlarıyla birleştirilmediği sürece satır kilitleri alınmaz.
ROWLOCK
kümelenmiş columnstore dizini olan bir tabloyla kullanılamaz. Aşağıdaki örnek, uygulamaya 651
UPDATE [dbo].[FactResellerSalesXL_CCI] WITH (ROWLOCK)
SET UnitPrice = 50
WHERE ProductKey = 150;
SERİLEŞTİRİLEBİLİR
HOLDLOCK
eşdeğerdir. İşlem tamamlanıp tamamlanmadığına bakılmaksızın, gerekli tablo veya veri sayfası artık gerekli olmadığında paylaşılan kilidi serbest bırakmak yerine, bir işlem tamamlanana kadar tutarak paylaşılan kilitleri daha kısıtlayıcı hale getirir. Tarama, SERIALIZABLE
yalıtım düzeyinde çalışan bir işlemle aynı semantikle gerçekleştirilir. Yalıtım düzeyleri hakkında daha fazla bilgi için bkz. SET TRANSACTION ISOLATION LEVEL.
AN -LIK GÖRÜNTÜ
için geçerlidir: SQL Server 2014 (12.x) ve sonraki sürümler
Bellek için iyileştirilmiş tabloya SNAPSHOT
yalıtım altında erişilir.
SNAPSHOT
, aşağıdaki örnekte görüldüğü gibi yalnızca bellek için iyileştirilmiş tablolarla (disk tabanlı tablolarda kullanılamaz) kullanılabilir. Daha fazla bilgi için bkz. Memory-Optimized Tablolarına Giriş.
SELECT *
FROM dbo.Customers AS c WITH (SNAPSHOT)
LEFT OUTER JOIN dbo.[Order History] AS oh
ON c.customer_id = oh.customer_id;
SPATIAL_WINDOW_MAX_CELLS = <integer_value>
için geçerlidir: SQL Server 2012 (11.x) ve sonraki sürümler
Geometri veya coğrafya nesnesini döşemek için kullanılacak en fazla hücre sayısını belirtir. <integer_value> 1 ile 8192 arasında bir değerdir.
Bu seçenek, birincil ve ikincil filtre yürütme süresi arasındaki dengeyi ayarlayarak sorgu yürütme süresinde ince ayar yapılmasını sağlar. Daha büyük bir sayı ikincil filtre yürütme süresini azaltır, ancak birincil yürütme filtresi süresini artırır ve daha küçük bir sayı birincil filtre yürütme süresini azaltır, ancak ikincil filtre yürütme süresini artırır. Daha yoğun uzamsal veriler için, daha yüksek bir sayı birincil filtreyle daha iyi bir tahmin sağlayarak ve ikincil filtre yürütme süresini azaltarak daha hızlı bir yürütme süresi üretmelidir. Daha seyrek veriler için, daha düşük bir sayı birincil filtre yürütme süresini azaltır.
Bu seçenek hem el ile hem de otomatik kılavuz döşemeleri için çalışır.
TABLOCK
Alınan kilidin tablo düzeyinde uygulandığını belirtir. Alınan kilit türü yürütülen deyimine bağlıdır. Örneğin, bir SELECT
deyimi paylaşılan bir kilit alabilir.
TABLOCK
belirterek, paylaşılan kilit satır veya sayfa düzeyi yerine tablonun tamamına uygulanır.
HOLDLOCK
de belirtilirse, tablo kilidi işlemin sonuna kadar tutulur.
INSERT INTO <target_table> SELECT <columns> FROM <source_table>
deyimini kullanarak verileri bir yığına aktarırken, hedef tablo için TABLOCK
ipucunu belirterek deyimi için en düşük günlüğe kaydetmeyi ve en iyi kilitlemeyi etkinleştirebilirsiniz. Ayrıca, veritabanının kurtarma modeli basit veya toplu günlüğe kaydedilmiş olarak ayarlanmalıdır.
TABLOCK
ipucu, yığınlara veya kümelenmiş columnstore dizinlerine paralel eklemeler de sağlar. Daha fazla bilgi için bkz. insert
OPENROWSET toplu satır kümesi sağlayıcısıyla verileri tabloya aktarmak için kullanıldığında, TABLOCK
birden çok istemcinin en iyi duruma getirilmiş günlüğe kaydetme ve kilitleme ile verileri hedef tabloya eşzamanlı olarak yüklemesini sağlar. Daha fazla bilgi için bkz. toplu içeri aktarmaminimum günlük kaydı için önkoşullar
TABLOCKX
Tabloda özel bir kilit alındığını belirtir.
UPDLOCK
İşlem tamamlanana kadar güncelleştirme kilitlerinin alınıp tutulacaklarını belirtir.
UPDLOCK
yalnızca satır düzeyinde veya sayfa düzeyinde okuma işlemleri için güncelleştirme kilitleri alır.
UPDLOCK
TABLOCK
ile birleştirilirse veya başka bir nedenle tablo düzeyinde kilit alınırsa, bunun yerine özel (X) bir kilit alınır.
UPDLOCK
belirtildiğinde, READCOMMITTED
ve READCOMMITTEDLOCK
yalıtım düzeyi ipuçları yoksayılır. Örneğin, oturumun yalıtım düzeyi SERIALIZABLE
olarak ayarlanırsa ve bir sorgu (UPDLOCK
, READCOMMITTED
), READCOMMITTED
ipucu yoksayılır ve işlem SERIALIZABLE
yalıtım düzeyi kullanılarak çalıştırılır.
XLOCK
İşlem tamamlanana kadar özel kilitlerin alınıp tutulacaklarını belirtir.
ROWLOCK
, PAGLOCK
veya TABLOCK
ile belirtilirse, özel kilitler uygun ayrıntı düzeyine uygulanır.
Açıklamalar
Tabloya sorgu planı tarafından erişilmeyen tablo ipuçları yoksayılır. Bunun nedeni iyileştiricinin tabloya hiç erişmeme seçeneğini belirlemesi veya bunun yerine dizinli bir görünüme erişilmesi olabilir. İkinci durumda, OPTION (EXPAND VIEWS)
sorgu ipucu kullanılarak dizinli görünüme erişim engellenebilir.
Tüm kilit ipuçları, bir görünümde başvurulan tablolar ve görünümler de dahil olmak üzere sorgu planı tarafından erişilen tüm tablolara ve görünümlere yayılır. Ayrıca, SQL Server ilgili kilit tutarlılığı denetimlerini gerçekleştirir.
Satır düzeyi kilitleri alan , UPDLOCK
ve XLOCK
ROWLOCK
kilit ipuçları, gerçek veri satırları yerine dizin anahtarlarına kilitler yerleştirebilir. Örneğin, bir tablonun bir kümelenmemiş dizini varsa ve kilit ipucu kullanan bir SELECT
deyimi kapsayan dizin tarafından işlenirse, temel tablodaki veri satırında değil, kapsayan dizindeki dizin anahtarında bir kilit alınır.
Tablo, diğer tablolardaki sütunlara erişen ifadeler veya işlevler tarafından hesaplanan hesaplanan sütunlar içeriyorsa, tablo ipuçları bu tablolarda kullanılmaz ve yayılmaz. Örneğin, sorgudaki bir tabloda NOLOCK
tablo ipucu belirtilir. Bu tabloda, başka bir tablodaki sütunlara erişen ifadelerin ve işlevlerin bir bileşimiyle hesaplanan sütunlar vardır. İfadeler ve işlevler tarafından başvuruda bulunan tablolar, erişildiğinde NOLOCK
tablo ipucunu kullanmaz.
SQL Server, FROM
yan tümcesindeki her tablo için aşağıdaki grupların her birinden birden fazla tablo ipucuna izin vermez:
- Ayrıntı ipuçları:
PAGLOCK
,NOLOCK
,READCOMMITTEDLOCK
,ROWLOCK
,TABLOCK
veyaTABLOCKX
. - Yalıtım düzeyi ipuçları:
HOLDLOCK
,NOLOCK
,READCOMMITTED
,REPEATABLEREAD
,SERIALIZABLE
.
Filtrelenmiş dizin ipuçları
Filtrelenmiş dizin tablo ipucu olarak kullanılabilir, ancak sorgunun seçtiği tüm satırları kapsamazsa sorgu iyileştiricisinin 8622 hatası oluşturmasına neden olur. Aşağıda geçersiz bir filtrelenmiş dizin ipucu örneği verilmiştir. Örnek, filtrelenmiş dizin FIBillOfMaterialsWithComponentID
oluşturur ve bunu bir SELECT
deyimi için dizin ipucu olarak kullanır. Filtrelenmiş dizin koşulu ComponentIDs 533, 324 ve 753 için veri satırları içerir. Sorgu koşulu ayrıca ComponentID'ler 533, 324 ve 753 için veri satırları içerir, ancak sonuç kümesini filtrelenmiş dizinde olmayan ComponentID'leri 855 ve 924 içerecek şekilde genişletir. Bu nedenle, sorgu iyileştirici filtrelenmiş dizin ipucunu kullanamaz ve 8622 hatasını oluşturur. Daha fazla bilgi için bkz.filtrelenmiş dizinler oluşturma
IF EXISTS (SELECT name FROM sys.indexes
WHERE name = N'FIBillOfMaterialsWithComponentID'
AND object_id = OBJECT_ID(N'Production.BillOfMaterials'))
DROP INDEX FIBillOfMaterialsWithComponentID
ON Production.BillOfMaterials;
GO
CREATE NONCLUSTERED INDEX [FIBillOfMaterialsWithComponentID]
ON Production.BillOfMaterials(ComponentID, StartDate, EndDate)
WHERE ComponentID IN (533, 324, 753);
GO
SELECT StartDate, ComponentID
FROM Production.BillOfMaterials
WITH (INDEX (FIBillOfMaterialsWithComponentID))
WHERE ComponentID IN (533, 324, 753, 855, 924);
GO
SET
seçenekleri filtrelenmiş dizinler için gerekli değerlere sahip değilse sorgu iyileştiricisi dizin ipucunu dikkate almaz. Daha fazla bilgi için bkz. CREATE INDEX
NOEXPAND kullanma
NOEXPAND
ipucunu belirtmeden dizinlenmiş görünümlerin otomatik kullanımını da destekler.
Daha fazla bilgi için bkz.sorgu işleme mimarisi kılavuzu
Windows'da SQL Server sürümleri tarafından desteklenen özelliklerin listesi için bkz:
- SQL Server 2022'nin Sürümleri ve desteklenen özellikleri
- SQL Server 2019'nin
Sürümleri ve desteklenen özellikleri - SQL Server 2017'nin Sürümleri ve desteklenen özellikleri
- SQL Server 2016'nın Sürümleri ve desteklenen özellikleri
Ancak, sorgu iyileştiricisinin eşleşen dizinli görünümleri dikkate alması veya NOEXPAND
ipucuyla başvuruda bulunılan dizinli bir görünüm kullanması için aşağıdaki SET
seçeneklerinin ON
olarak ayarlanması gerekir.
- ANSI_NULLS
- ANSI_PADDING
- ANSI_WARNINGS
- ARITHABORT 1
- CONCAT_NULL_YIELDS_NULL
- QUOTED_IDENTIFIER
1ARITHABORT
, ANSI_WARNINGS
ON
olarak ayarlandığında örtük olarak ON
olarak ayarlanır. Bu nedenle, bu ayarı el ile ayarlamanız gerekmez.
Ayrıca, NUMERIC_ROUNDABORT
seçeneği OFF
olarak ayarlanmalıdır.
Sorgu iyileştiricisini dizinlenmiş görünümde dizin kullanmaya zorlamak için NOEXPAND
seçeneğini belirtin. Bu ipucu yalnızca görünüm sorguda da adlandırılmışsa kullanılabilir. SQL Server, görünümü doğrudan FROM
yan tümcesinde adlandırmayan bir sorguda belirli bir dizinlenmiş görünümün kullanılmasını zorlamak için bir ipucu sağlamaz. Ancak sorgu iyileştiricisi, doğrudan sorguda başvurulmasa bile dizine alınmış görünümleri kullanmayı göz önünde bulundurr. SQL Server Veritabanı Altyapısı yalnızca NOEXPAND
tablo ipucu kullanıldığında dizinli görünümde otomatik olarak istatistikler oluşturur. Bu ipucunu atlayarak, istatistikler el ile oluşturularak çözümlenebilen eksik istatistikler hakkında yürütme planı uyarılarına yol açabilir.
Sorgu iyileştirme sırasında Veritabanı Altyapısı, sorgu doğrudan görünüme başvurduğunda ve NOEXPAND
ipucu kullanıldığında otomatik olarak veya el ile oluşturulan görünüm istatistiklerini kullanır.
Sorgu ipucu olarak tablo ipucu kullanma
Tablo ipuçlarıOPTION (TABLE HINT)
yan tümcesi kullanılarak sorgu ipucu olarak da belirtilebilir. Sorgu ipucu olarak yalnızca
İzinler
KEEPIDENTITY
, IGNORE_CONSTRAINTS
ve IGNORE_TRIGGERS
ipuçları tabloda ALTER
izinler gerektirir.
Örnekler
A. Kilitleme yöntemi belirtmek için TABLOCK ipucunu kullanın
Aşağıdaki örnek, AdventureWorks2022 veritabanındaki Production.Product
tablosunda paylaşılan bir kilidin alındığını ve UPDATE
deyiminin sonuna kadar tutulduğunu belirtir.
UPDATE Production.Product WITH (TABLOCK)
SET ListPrice = ListPrice * 1.10
WHERE ProductNumber LIKE 'BK-%';
GO
B. Dizin arama işlemini belirtmek için FORCESEEK ipucunu kullanın
Aşağıdaki örnek, sorgu iyileştiricisini AdventureWorks2022 veritabanındaki Sales.SalesOrderDetail
tablosunda dizin arama işlemi gerçekleştirmeye zorlamak için dizin belirtmeden FORCESEEK
ipucunu kullanır.
SELECT *
FROM Sales.SalesOrderHeader AS h
INNER JOIN Sales.SalesOrderDetail AS d WITH (FORCESEEK)
ON h.SalesOrderID = d.SalesOrderID
WHERE h.TotalDue > 100
AND (d.OrderQty > 5
OR d.LineTotal < 1000.00);
GO
Aşağıdaki örnek, sorgu iyileştiricisini belirtilen dizin ve dizin sütununda dizin arama işlemi gerçekleştirmeye zorlamak için dizinle FORCESEEK
ipucunu kullanır.
SELECT h.SalesOrderID,
h.TotalDue,
d.OrderQty
FROM Sales.SalesOrderHeader AS h
INNER JOIN Sales.SalesOrderDetail AS d
WITH (FORCESEEK (PK_SalesOrderDetail_SalesOrderID_SalesOrderDetailID (SalesOrderID)))
ON h.SalesOrderID = d.SalesOrderID
WHERE h.TotalDue > 100
AND (d.OrderQty > 5
OR d.LineTotal < 1000.00);
GO
C. Dizin tarama işlemi belirtmek için FORCESCAN ipucunu kullanın
Aşağıdaki örnek, sorgu iyileştiricisini AdventureWorks2022 veritabanındaki Sales.SalesOrderDetail
tablosunda tarama işlemi gerçekleştirmeye zorlamak için FORCESCAN
ipucunu kullanır.
SELECT h.SalesOrderID,
h.TotalDue,
d.OrderQty
FROM Sales.SalesOrderHeader AS h
INNER JOIN Sales.SalesOrderDetail AS d WITH (FORCESCAN)
ON h.SalesOrderID = d.SalesOrderID
WHERE h.TotalDue > 100
AND (d.OrderQty > 5
OR d.LineTotal < 1000.00);
İlgili içerik
- OPENROWSET (Transact-SQL)
- İpuçları (Transact-SQL)
- Sorgu ipuçları (Transact-SQL)