Neden bir tablo değişkeni kullanarak bir dizin arama ve sonra yer işareti arama karşı bir yer imi arama kullanarak optimize edici önleyici olduğunu anlamaya çalışıyorum.
Masayı doldurmak:
CREATE TABLE dbo.Test
(
RowKey INT NOT NULL PRIMARY KEY,
SecondColumn CHAR(1) NOT NULL DEFAULT 'x',
ForeignKey INT NOT NULL
)
INSERT dbo.Test
(
RowKey,
ForeignKey
)
SELECT TOP 1000000
ROW_NUMBER() OVER (ORDER BY (SELECT 0)),
ABS(CHECKSUM(NEWID()) % 10)
FROM sys.all_objects s1
CROSS JOIN sys.all_objects s2
CREATE INDEX ix_Test_1 ON dbo.Test (ForeignKey)
Bir tablo değişkenini tek bir kayıtla doldurun ve yabancı anahtar sütununda arama yaparak birincil anahtarı ve ikinci sütunu aramaya çalışın:
DECLARE @Keys TABLE (RowKey INT NOT NULL)
INSERT @Keys (RowKey) VALUES (10)
SELECT
t.RowKey,
t.SecondColumn
FROM
dbo.Test t
INNER JOIN
@Keys k
ON
t.ForeignKey = k.RowKey
Uygulama planı aşağıdadır:
Şimdi aynı sorgu yerine geçici tablo kullanarak:
CREATE TABLE #Keys (RowKey INT NOT NULL)
INSERT #Keys (RowKey) VALUES (10)
SELECT
t.RowKey,
t.SecondColumn
FROM
dbo.Test t
INNER JOIN
#Keys k
ON
t.ForeignKey = k.RowKey
Bu sorgu planı bir arama ve yer işareti araması kullanır:
Optimizer neden yer değişkeni temp tablosuyla arama yapıyor, ancak table değişkeni ile değil?
Tablo değişkeni bu örnekte, saklı yordamda kullanıcı tanımlı bir tablo türünden gelen verileri temsil etmek için kullanılır.
Yabancı anahtar değeri yüzbinlerce kez gerçekleştiğinde endeks arayışının uygun olmayabileceğini biliyorum. Bu durumda, tarama muhtemelen daha iyi bir seçim olacaktır. Oluşturduğum senaryo için, değeri 10 olan bir satır yoktu. Davranışın ilginç olduğunu ve bunun bir nedeni olup olmadığını bilmek istiyorum.
Ekleme OPTION (RECOMPILE)
davranışı değiştirmedi. UDDT'nin birincil anahtarı vardır.
@@VERSION
Server 2008 R2 (SP2) - 10.50.4042.0 (X64) (Derleme 7601: Service Pack 1) nedir (Hipervizör)