SQL Server, TOP contre ROW_NUMBER

8

J'apprends les plans d'exécution et j'essaie différentes requêtes et je compare leurs performances et je suis tombé sur ceci:

SELECT StatisticID
FROM (
    SELECT StatisticID, ROW_NUMBER() OVER (ORDER BY StatisticID) AS rn
    FROM FTCatalog.Statistic
    ) AS T
WHERE T.rn <= 1000
ORDER BY rn

SELECT TOP 1000 StatisticID
FROM FTCatalog.Statistic
ORDER BY StatisticID

Ils retournent tous les deux le même jeu de résultats - cependant le premier s'exécute plus rapidement et consomme moins de ressources (au moins SSMS me le dit) Voici les plans d'exécution: Plans d'exécution

Comparaison de SQL Query Plan Explorer: entrez la description de l'image ici Quelqu'un pourrait-il me donner un aperçu de ce qui se passe réellement dans les coulisses et pourquoi les résultats diffèrent? S'il y a autre chose dont vous avez besoin - faites le moi savoir.

Merci, Evaldas.

Evaldas Buinauskas
la source
Pour une raison quelconque, SQL Server n'a pas de bonnes réécritures de requêtes pour les requêtes de pagination. Ces différences de plan et d'estimation ne devraient pas exister dans un cas aussi courant.
usr

Réponses:

11

Je suppose que vous comparez les coûts estimés pour les requêtes. Ce ne sont que des estimations basées sur (entre autres) le nombre estimé de lignes renvoyées par la requête. Pas le nombre réel de lignes.

Votre première requête a estimé qu'elle retournerait 30 lignes et votre deuxième requête a estimé 1000 lignes. C'est de là que vient votre différence de coût de requête.

Si vous modifiez les requêtes pour extraire seulement 30 lignes, vous verrez que les lignes estimées sont les mêmes pour les requêtes et que la première requête est en fait un peu plus chère, du moins pour moi dans SQL Server 2014.

N'utilisez pas les estimations lorsque vous comparez les performances des requêtes. Utilisez plutôt des choses comme la durée, le nombre de lectures et la taille des allocations de mémoire.

Mikael Eriksson
la source
1
Pour vérifier les performances réelles, exécutez chacune des requêtes plusieurs fois (GO 10) avec l'option Inclure les statistiques du client. Je suppose que vous constaterez que les temps d'exécution réels sont plus proches que les estimations de coûts relatifs. Il n'y a pas de magie sous les couvertures; les opérateurs du plan de requête racontent la vraie histoire.
Dan Guzman
Le coût relatif (expression en pourcentage) signifie-t-il réellement quelque chose dans SSMS? Cela me dérangeait le plus.
Evaldas Buinauskas
@EvaldasBuinauskas Je ne sais pas si le coût relatif est utile pour quoi que ce soit. Peut-être parfois, mais je ne pense pas que cela puisse valoir toute la confusion que cela crée lorsque les gens commencent à utiliser le pourcentage estimé pour comparer les performances de différentes requêtes. Ce sera toujours une estimation et les estimations sont toujours (presque) fausses.
Mikael Eriksson
@EvaldasBuinauskas, ces coûts sont collectés pendant le processus d'optimisation et exposés, mais ne sont pas destinés à être un indicateur ou des durées d'exécution réelles. Les coûts sont juste une meilleure estimation. Voir blogs.msdn.com/b/sqlqueryprocessing/archive/2006/10/11/…
Dan Guzman