Saya sedang bereksperimen dengan indeks untuk mempercepat hal-hal, tetapi dalam kasus bergabung, indeks tidak meningkatkan waktu eksekusi permintaan dan dalam beberapa kasus memperlambat hal-hal.
Permintaan untuk membuat tabel uji dan mengisinya dengan data adalah:
CREATE TABLE [dbo].[IndexTestTable](
[id] [int] IDENTITY(1,1) PRIMARY KEY,
[Name] [nvarchar](20) NULL,
[val1] [bigint] NULL,
[val2] [bigint] NULL)
DECLARE @counter INT;
SET @counter = 1;
WHILE @counter < 500000
BEGIN
INSERT INTO IndexTestTable
(
-- id -- this column value is auto-generated
NAME,
val1,
val2
)
VALUES
(
'Name' + CAST((@counter % 100) AS NVARCHAR),
RAND() * 10000,
RAND() * 20000
);
SET @counter = @counter + 1;
END
-- Index in question
CREATE NONCLUSTERED INDEX [IndexA] ON [dbo].[IndexTestTable]
(
[Name] ASC
)
INCLUDE ( [id],
[val1],
[val2])
Sekarang kueri 1, yang ditingkatkan (hanya sedikit tetapi peningkatannya konsisten) adalah:
SELECT *
FROM IndexTestTable I1
JOIN IndexTestTable I2
ON I1.ID = I2.ID
WHERE I1.Name = 'Name1'
Stat dan rencana eksekusi tanpa Indeks (dalam hal ini tabel menggunakan indeks berkerumun standar):
(5000 row(s) affected)
Table 'IndexTestTable'. Scan count 2, logical reads 5580, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
(1 row(s) affected)
SQL Server Execution Times:
CPU time = 109 ms, elapsed time = 294 ms.
Sekarang dengan Indeks diaktifkan:
(5000 row(s) affected)
Table 'IndexTestTable'. Scan count 2, logical reads 2819, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
(1 row(s) affected)
SQL Server Execution Times:
CPU time = 94 ms, elapsed time = 231 ms.
Sekarang kueri yang melambat karena indeks (kueri tidak berarti karena dibuat hanya untuk pengujian):
SELECT I1.Name,
SUM(I1.val1),
SUM(I1.val2),
MIN(I2.Name),
SUM(I2.val1),
SUM(I2.val2)
FROM IndexTestTable I1
JOIN IndexTestTable I2
ON I1.Name = I2.Name
WHERE
I2.Name = 'Name1'
GROUP BY
I1.Name
Dengan diaktifkan indeks berkerumun:
(1 row(s) affected)
Table 'IndexTestTable'. Scan count 4, logical reads 60, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 1, logical reads 155106, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
(1 row(s) affected)
SQL Server Execution Times:
CPU time = 17207 ms, elapsed time = 17337 ms.
Sekarang dengan Indeks dinonaktifkan:
(1 row(s) affected)
Table 'IndexTestTable'. Scan count 5, logical reads 8642, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 2, logical reads 165212, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
(1 row(s) affected)
SQL Server Execution Times:
CPU time = 17691 ms, elapsed time = 9073 ms.
Pertanyaannya adalah:
- Meskipun indeks disarankan oleh SQL Server, mengapa indeks memperlambat segalanya karena perbedaan yang signifikan?
- Apa yang bergabung dengan Nested Loop yang menghabiskan sebagian besar waktu dan cara meningkatkan waktu pelaksanaannya?
- Adakah sesuatu yang saya lakukan salah atau telah terlewatkan?
- Dengan indeks default (hanya pada kunci utama) mengapa diperlukan waktu lebih sedikit, dan dengan indeks non-cluster hadir, untuk setiap baris dalam tabel bergabung, baris tabel bergabung harus ditemukan lebih cepat, karena bergabung adalah pada kolom Nama di mana indeks telah dibuat. Ini tercermin dalam rencana eksekusi permintaan dan biaya Pencarian Indeks lebih rendah ketika IndexA aktif, tetapi mengapa masih lebih lambat? Juga apa yang ada di Nested Loop kiri luar yang menyebabkan perlambatan?
Menggunakan SQL Server 2012