Mari kita lemparkan satu juta baris ke tabel temp bersama dengan beberapa kolom:
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);
Di sini saya memiliki indeks berkerumun (secara default) pada PK
kolom. Ada indeks nonclustered pada COL1
yang memiliki kolom kunci COL1
dan sertakan COL2
.
Pertimbangkan pertanyaan berikut:
SELECT *
FROM #174860
WHERE PK >= 15000 AND PK < 15005
AND COL2 = 5000;
Di sini saya tidak menggunakan BETWEEN
karena Aaron Bertrand berkeliaran di pertanyaan ini.
Bagaimana seharusnya pengoptimal SQL Server SQL permintaan? Yah, saya tahu bahwa filter aktif PK
akan mengurangi hasil yang ditetapkan ke lima baris. SQL server dapat menggunakan indeks berkerumun untuk melompat ke lima baris alih-alih membaca semua juta baris dalam tabel. Namun, indeks berkerumun hanya memiliki kolom PK sebagai kolom kunci. Setelah baris dibaca ke dalam memori, kita perlu menerapkan filter COL2
. Di sini, PK
predikat mencari dan COL2
predikat.
SQL server menemukan lima baris menggunakan predikat seek dan selanjutnya mengurangi lima baris tersebut menjadi satu baris dengan predikat normal.
Jika saya mendefinisikan indeks klaster berbeda:
CREATE TABLE #174860 (
PK INT NOT NULL,
COL1 INT NOT NULL,
COL2 INT NOT NULL,
PRIMARY KEY (COL2, PK)
);
Dan jalankan kueri yang sama saya mendapatkan hasil yang berbeda:
Dalam hal ini, SQL Server dapat mencari menggunakan kedua kolom dalam WHERE
klausa. Tepat satu baris dibaca dari tabel menggunakan kolom kunci.
Untuk satu contoh lagi pertimbangkan pertanyaan ini:
SELECT *
FROM #174860
WHERE COL1 = 500
AND COL2 = 3545;
Indeks IX_174860_IX adalah indeks penutup karena berisi semua kolom yang diperlukan untuk kueri. Namun, hanya COL1
kolom kunci. SQL Server dapat mencari dengan kolom itu untuk menemukan 1000 baris dengan COL1
nilai yang cocok . Lebih lanjut dapat menyaring baris-baris pada COL2
kolom untuk mengurangi hasil akhir yang ditetapkan ke 0 baris.