TSQL Pourquoi Top est-il plus rapide avec une variable?

10

Bonjour à tous,

J'ai travaillé sur un SQL modérément complexe pour «obtenir» certaines données d'une base de données de produits tiers, pour les afficher dans nos propres applications internes.

J'ai ajouté une sélection pour obtenir l'enregistrement supérieur d'une table dans une sous-requête (si cela a du sens)

la requête a pris près de 3 minutes pour renvoyer un jeu de résultats final de 100 enregistrements en utilisant

SELECT TOP 1 ...

J'ai cherché en ligne des améliorations à ce que j'essayais de réaliser et il m'a été suggéré de modifier ma sélection pour utiliser une variable, comme ci-dessous

DECLARE @topCount INT
SET @topCount = 1

SELECT TOP (@topCount) ...

Cela a pris la même requête des 3 minutes à 1 seconde, ce qui est génial!

Mais quelqu'un peut-il expliquer pourquoi il en est ainsi?

JamesStuddart
la source

Réponses:

14

Lorsque vous effectuez top 1l'optimiseur de requête, un plan est créé pour récupérer une ligne aussi rapidement que possible.

Lorsque vous utilisez une variable locale, la valeur de la variable est inconnue de l'optimiseur et crée à la place un plan optimisé pour extraire 100 lignes le plus rapidement possible.

Dans votre cas, le plan de requête généré avec un objectif de ligne de 100 est le meilleur plan à utiliser même lorsque vous ne souhaitez qu'une seule ligne.

Pour vérifier, vous pouvez essayer d'ajouter option (recompile)à votre requête avec la variable. Dans ce cas, SQL Server utilisera la valeur actuelle de @topCountcomme objectif de ligne et puisque c'est 1, vous devriez obtenir le plan lent.

Mikael Eriksson
la source
Je comprends la différence de plan, mais cela m'étonne que l'extraction d'une ligne puisse être plus lente que l'extraction de 100 lignes. Je pense que si le plan à 100 lignes fonctionne mieux, SQL Server utiliserait le même plan pour top 1.
Brandon
@Brandon ne récupère pas 100 lignes, construit uniquement le plan d'exécution avec l'hypothèse que 100 lignes sont ce qui est souhaité. L'exécution se termine lorsqu'une ligne est trouvée.
Mikael Eriksson
Vérifier ce qui est différent avec le plan d'exécution dans ces cas aiderait probablement à comprendre quel est le problème avec le top 1.
James Z