web-dev-qa-db-fra.com

Que fait OPTION FAST dans l'instruction SELECT?

J'ai fait quelques recherches sur ce que fait l'indicateur de requête OPTION (FAST XXX) dans une instruction SELECT et je suis toujours confus. Selon MSDN:

Spécifie que la requête est optimisée pour une récupération rapide des premières number_rows. Il s'agit d'un entier non négatif. Une fois les premières number_rows renvoyées, la requête continue son exécution et produit son jeu de résultats complet.

Pour moi, cela n'a pas beaucoup de sens mais, fondamentalement, la requête peut obtenir les premières XXX lignes très rapidement, puis les autres à vitesse normale?

La requête Microsoft Dynamics qui m'a fait réfléchir est la suivante:

select pjproj.project,pjproj.project_desc,pjproj.customer,pjproj.cpnyid
from pjproj WITH (NOLOCK)
where project like  '%'
order by project OPTION(FAST 500)

Quelqu'un peut-il expliquer exactement ce que fait cet indice de requête et son avantage par rapport à ne pas l'utiliser?

31
Matthew Verstraete

Un FAST N Indiquera à SQL Server de générer un plan d'exécution avec un retour rapide du nombre de lignes définies comme N.

Notez que les estimations seront conformes à N puisque vous dites au serveur sql de récupérer N lignes le plus rapidement possible.

par exemple. exécutant la requête ci-dessous avec fast 500:

-- total rows : 19972
 SELECT [BusinessEntityID]
      ,[TotalPurchaseYTD]
      ,[DateFirstPurchase]
      ,[BirthDate]
      ,[MaritalStatus]
      ,[YearlyIncome]
      ,[Gender]
      ,[TotalChildren]
      ,[NumberChildrenAtHome]
      ,[Education]
      ,[Occupation]
      ,[HomeOwnerFlag]
      ,[NumberCarsOwned]
  FROM [AdventureWorks2012].[Sales].[vPersonDemographics]
  order by BusinessEntityID
  option (fast 500)

Est vs lignes réelles avec option (fast 500)

enter image description here

Est vs lignes réelles sans option (fast 500)

enter image description here

Un cas d'utilisation serait lorsqu'une application effectue la mise en cache (charge une grande quantité de données en arrière-plan) et souhaite montrer à l'utilisateur une tranche de données aussi rapidement que possible.

Un autre cas d'utilisation intéressant est dans SSIS land que Rob Farley décrit l'utilisation de FAST N Comme catalyseur accélérant la récupération des données.

En ajoutant cet indice, on avait l'impression qu'une baguette magique avait été agitée sur la requête, pour la faire fonctionner plusieurs fois plus rapidement.

Voir la réponse de Remus Rusanu également .

26
Kin Shah

Lorsque vous utilisez cette option de requête OPTION (FAST n), l'optimiseur sélectionne un plan d'exécution qui peut renvoyer cette quantité d'enregistrements de la manière la plus rapide possible. Normalement, l'optimiseur essaie de décider d'un chemin qui peut renvoyer efficacement l'ensemble de résultats complet. Donc, si vous souhaitez qu'un ensemble de lignes revienne rapidement, vous pouvez éventuellement l'utiliser pour les récupérer, mais dans la plupart des cas, l'utilisation de cet indice entraînera le retour de l'ensemble des résultats plus lentement que de laisser l'optimiseur utiliser un plan pour le faire donc.

Juste pour développer un cas d'utilisation: vous pouvez avoir deux tables assez grandes que vous devez réunir, mais vous savez qu'il n'y a qu'un ensemble de données plus petit avec lequel vous devez travailler avec l'une d'entre elles. Dans ce cas, l'utilisation de FAST sur une table plus grande sans avoir à créer d'index/surcharge supplémentaires pourrait aider au lieu de laisser SQL créer une table de hachage géante en arrière-plan.

14
codedawg82

Je suis tombé sur la même question il y a quelques années en étudiant les problèmes de performances dans Dynamics AX. Après l'explication de Microsoft, j'ai pu voir un plan d'exécution différent déclenché par l'indice et cela correspond aux autres réponses données ici.

Avec cet indice, SQL Server essaie de trouver un plan d'exécution qui permet une sorte de streaming des résultats, car ils sortent d'une boucle imbriquée par exemple, au lieu d'un plan d'exécution qui nécessite que tous les enregistrements soient lus (et potentiellement triés) avant étant sortie.

Le seul problème dans mon cas est que le serveur SQL a toujours pris (de nombreuses) minutes pour renvoyer les résultats lors de l'utilisation de l'indicateur, tandis que la requête a renvoyé les résultats (l'ensemble des résultats) en quelques secondes sans l'indication ... pas tout à fait quoi était attendu. J'utiliserais personnellement cette astuce avec beaucoup de prudence, et pas systématiquement sur toutes les formes comme dans notre environnement Dynamics (enfin, plus maintenant).

Donc, pour répondre à l'OP: comme beaucoup d'indices, cela n'aide pas nécessairement à améliorer la requête comme il est censé le faire (alors ... test, test, test!)

3
Nelson 2.0