Une explication possible se trouve ici dans le commentaire
Dans SQL Server 2014 Enterprise Edition (64-bit) - j'essaie de lire à partir d'une vue. Une requête standard contient juste un ORDER BY
et OFFSET-FETCH
clause comme celle-ci.
Approche 1
SELECT
*
FROM Metadata
ORDER BY
AgeInHours ASC,
RankingPoint DESC,
PublishDate DESC
OFFSET 150000 ROWS
FETCH NEXT 40 ROWS ONLY
Cependant, cette requête assez simple donne des résultats presque identiques à ceux de l'année précédente. 9 fois plus lent (visible lorsque l'on saute un grand nombre de lignes comme 150k) que la requête suivante qui renvoie le même résultat.
Dans ce cas, je lis d'abord la clé primaire, puis je l'utilise comme paramètre pour la commande WHERE...IN
fonction
Approche 2
SELECT
*
FROM Metadata
WHERE NewsId IN (
SELECT
NewsId
FROM Metadata
ORDER BY
AgeInHours ASC,
RankingPoint DESC,
PublishDate DESC
OFFSET 150000 ROWS
FETCH NEXT 40 ROWS ONLY
)
ORDER BY
AgeInHours ASC,
RankingPoint DESC,
PublishDate DESC
L'analyse comparative de ces deux éléments fait apparaître la différence suivante
(40 row(s) affected)
SQL Server Execution Times:
CPU time = 14748 ms, elapsed time = 3329 ms.
(40 row(s) affected)
SQL Server Execution Times:
CPU time = 3828 ms, elapsed time = 469 ms.
J'ai des index sur la clé primaire, PubilshDate
et leur fragmentation est très faible. J'ai également essayé d'exécuter des requêtes similaires sur la table de la base de données, mais dans tous les cas, la deuxième approche permet d'obtenir des gains de performance importants. J'ai également testé cette méthode sur SQL Server 2012.
Quelqu'un peut-il nous expliquer ce qui se passe ?
Schéma
Approche 1 : Plan d'exécution
Approche 2 : Plan d'exécution (partie gauche)
Approche 2 : Plan d'exécution (partie droite)