Ich habe mit Indizes experimentiert, um die Dinge zu beschleunigen, aber im Falle eines Joins verbessert der Index nicht die Ausführungszeit für Abfragen und in einigen Fällen verlangsamt er die Dinge.
Die Abfrage, um eine Testtabelle zu erstellen und mit Daten zu füllen, lautet:
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])
Jetzt ist Abfrage 1, die verbessert wird (nur geringfügig, aber die Verbesserung ist konsistent):
SELECT *
FROM IndexTestTable I1
JOIN IndexTestTable I2
ON I1.ID = I2.ID
WHERE I1.Name = 'Name1'
Statistik und Ausführungsplan ohne Index (in diesem Fall verwendet die Tabelle den standardmäßigen Clustered-Index):
(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.
Jetzt mit aktiviertem Index:
(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.
Nun die Abfrage, die sich aufgrund des Index verlangsamt (die Abfrage ist bedeutungslos, da sie nur zu Testzwecken erstellt wird):
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
Mit aktiviertem Clustered Index:
(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.
Jetzt mit deaktiviertem Index:
(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.
Die Fragen sind:
- Obwohl der Index vom SQL Server vorgeschlagen wird, warum verlangsamt er die Dinge um einen signifikanten Unterschied?
- Was ist der Nested Loop-Join, der die meiste Zeit in Anspruch nimmt und wie kann die Ausführungszeit verbessert werden?
- Gibt es etwas, das ich falsch mache oder verpasst habe?
- Wenn der Standardindex (nur für Primärschlüssel) weniger Zeit in Anspruch nimmt und der nicht gruppierte Index für jede Zeile in der Verknüpfungstabelle vorhanden ist, sollte die verknüpfte Tabellenzeile schneller gefunden werden, da sich die Verknüpfung in der Spalte Name befindet, in der Der Index wurde erstellt. Dies spiegelt sich im Abfrageausführungsplan wider und die Kosten für die Indexsuche sind geringer, wenn IndexA aktiv ist. Warum jedoch immer noch langsamer? Auch was ist in der Nested Loop der linke äußere Join, der die Verlangsamung verursacht?
Verwenden von SQL Server 2012
quelle