J'essayais avec des index pour accélérer les choses, mais dans le cas d'une jointure, l'index n'améliore pas le temps d'exécution de la requête et, dans certains cas, il ralentit le processus.
La requête pour créer une table de test et la remplir avec des données est la suivante:
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])
Maintenant, la requête 1, qui est améliorée (légèrement mais l'amélioration est constante) est la suivante:
SELECT *
FROM IndexTestTable I1
JOIN IndexTestTable I2
ON I1.ID = I2.ID
WHERE I1.Name = 'Name1'
Statistiques et plan d'exécution sans index (dans ce cas, la table utilise l'index clusterisé par défaut):
(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.
Maintenant, avec l'index activé:
(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.
Maintenant, la requête qui ralentit en raison de l'index (la requête n'a pas de sens puisqu'elle est créée pour les tests uniquement):
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
Avec l'index clusterisé activé:
(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.
Maintenant avec Index désactivé:
(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.
Les questions sont:
- Bien que l'index soit suggéré par SQL Server, pourquoi ralentit-il les choses d'une différence significative?
- Quelle est la jointure de boucle imbriquée qui prend le plus de temps et comment améliorer son temps d'exécution?
- Y a-t-il quelque chose que je fais mal ou que j'ai manqué?
- Avec l'index par défaut (sur la clé primaire uniquement), pourquoi prend-il moins de temps, et avec l'index non en cluster présent, pour chaque ligne de la table de jointure, la ligne de la table jointe doit être trouvée plus rapidement, car join est dans la colonne Nom sur laquelle l'index a été créé. Cela se reflète dans le plan d'exécution de la requête et le coût de la recherche dans l'Index est inférieur lorsque IndexA est actif, mais pourquoi rester plus lent? De plus, que se passe-t-il dans la jointure externe gauche de la boucle imbriquée qui provoque le ralentissement?
Utiliser SQL Server 2012
la source