Birkaç sütunla birlikte geçici tabloya bir milyon satır atalım:
CREATE TABLE #174860 (
PK INT NOT NULL,
COL1 INT NOT NULL,
COL2 INT NOT NULL,
PRIMARY KEY (PK)
);
INSERT INTO #174860 WITH (TABLOCK)
SELECT RN
, RN % 1000
, RN % 10000
FROM
(
SELECT TOP 1000000 ROW_NUMBER () OVER (ORDER BY (SELECT NULL)) RN
FROM master..spt_values v1,
master..spt_values v2
) t;
CREATE INDEX IX_174860_IX ON #174860 (COL1) INCLUDE (COL2);
Burada PK
sütun üzerinde kümelenmiş bir dizin (varsayılan olarak) var . Üzerinde COL1
anahtar sütunu olan COL1
ve içeren kümelenmemiş bir dizin var COL2
.
Aşağıdaki sorguyu düşünün:
SELECT *
FROM #174860
WHERE PK >= 15000 AND PK < 15005
AND COL2 = 5000;
Burada kullanmıyorum BETWEEN
çünkü Aaron Bertrand bu sorunun etrafında duruyor.
SQL Server bu sorguyu nasıl optimize etmelidir? Açık olan filtrenin PK
sonuç kümesini beş satıra indireceğini biliyorum . SQL sunucusu, tablodaki tüm milyon satırları okumak yerine bu beş satıra atlamak için kümelenmiş dizini kullanabilir. Ancak, kümelenmiş dizin anahtar sütun olarak yalnızca PK sütununa sahiptir. Satır belleğe okunduktan sonra filtreyi uygulamalıyız COL2
. Burada, PK
bir arama yüklemidir ve COL2
bir yüklemdir.
SQL sunucusu, arama yüklemini kullanarak beş satır bulur ve bu beş satırı normal yüklemle bir satıra azaltır.
Kümelenmiş dizini farklı şekilde tanımlarsam:
CREATE TABLE #174860 (
PK INT NOT NULL,
COL1 INT NOT NULL,
COL2 INT NOT NULL,
PRIMARY KEY (COL2, PK)
);
Ve aynı sorguyu çalıştırmak Farklı sonuçlar alıyorum:
Bu durumda, SQL Server WHERE
yan tümcesinde her iki sütun kullanarak arama yapabilirsiniz . Anahtar sütunlar kullanılarak tablodan tam olarak bir satır okunur.
Bir örnek daha bu sorguyu düşünün:
SELECT *
FROM #174860
WHERE COL1 = 500
AND COL2 = 3545;
IX_174860_IX dizini, sorgu için gereken tüm sütunları içerdiğinden bir kaplama dizinidir. Ancak, yalnızca COL1
bir anahtar sütundur. SQL Server, eşleşen bir COL1
değere sahip 1000 satırı bulmak için bu sütunu arayabilir . COL2
Son sonucu 0 sıraya düşürmek için sütundaki bu satırları daha fazla filtreleyebilir .