33 votes

Quand un curseur FAST_FORWARD aura-t-il une table de travail (et est-ce quelque chose à éviter)?

Arrière-plan

J'ai remarqué tout en expérimentant avec un total de requêtes que, parfois, le plan estimé montre juste une "lecture de la Requête"

Fetch

et le plan montre répété Extrait à partir de l'Analyse d'Index Cluster

Fetch Scan

à d'autres occasions (e.g lors de l'ajout d'un TOP à la requête), l'estimation de plan montre une Population "Requête" de l'étape qui remplit une table de travail

Fetch and Populate

Avec le plan, montrant une analyse d'index cluster pour remplir la table de travail, puis répété cherche l'encontre de cette table de travail.

Seeks

Question

  1. Quels critères de SQL Server à utiliser dans le choix d'une approche plutôt que l'autre?
  2. Serais-je en droit de penser que la première méthode (sans la table de travail à l'étape de la population) est plus efficace?

(Question Bonus: Si quelqu'un pouvait expliquer pourquoi chaque analyse dans la première requête comtes comme 2 lectures logiques qui pourrait être tout à fait éclairant trop)

Des Informations Supplémentaires

J'ai trouvé cet article ici qui explique qu' FAST_FORWARD curseurs pouvez soit utiliser un plan dynamique ou un plan statique. La première requête dans ce cas semble être l'aide d'un plan dynamique et la deuxième un plan statique.

J'ai trouvé aussi que si j'essaie

SET @C2 = CURSOR DYNAMIC TYPE_WARNING FOR SELECT TOP ...

Le curseur devient implicitement converti en keyset curseur de sorte qu'il est clair que l' TOP construire n'est pas pris en charge pour les curseurs dynamiques, peut-être pour des raisons de Ruben réponse - Toujours à la recherche d'une explication définitive de cette.

Cependant j'ai aussi lu que les curseurs dynamiques ont tendance à être plus lent que leurs contre-parties statiques (source 1, source 2) qui semble surprenant pour moi, étant donné que la statique de la variété de lire la source de données, copie, alors lisez la copie plutôt que de simplement lire la source de données. L'article que j'ai mentionné plus tôt mentionne que les curseurs dynamiques utiliser markers. Quelqu'un peut-il expliquer de quoi il s'agit? Est-ce juste un RID ou de l'IC clé, ou quelque chose de différent?

Script

SET STATISTICS IO OFF

CREATE TABLE #T ( ord INT IDENTITY PRIMARY KEY, total INT, Filler char(8000))

INSERT INTO #T (total) VALUES (37),(80),(55),(31),(53)

DECLARE @running_total INT, 
    @ord INT, 
    @total INT

SET @running_total = 0
SET STATISTICS IO ON
DECLARE @C1 AS CURSOR;
SET @C1 = CURSOR FAST_FORWARD FOR SELECT ord, total FROM #T ORDER BY ord;
OPEN @C1;
PRINT 'Initial FETCH C1'
FETCH NEXT FROM @C1 INTO @ord, @total ;
WHILE @@FETCH_STATUS = 0
BEGIN
  SET @running_total = @running_total + @total
  PRINT 'FETCH C1'
  FETCH NEXT FROM @C1 INTO @ord, @total ;
END

SET @running_total = 0
SET STATISTICS IO ON
DECLARE @C2 AS CURSOR;
SET @C2 = CURSOR FAST_FORWARD FOR SELECT TOP 5 ord, total FROM #T ORDER BY ord;
OPEN @C2;
PRINT 'Initial FETCH C2'
FETCH NEXT FROM @C2 INTO @ord, @total ;
WHILE @@FETCH_STATUS = 0
BEGIN
  SET @running_total = @running_total + @total
  PRINT 'FETCH C2'
  FETCH NEXT FROM @C2 INTO @ord, @total ;
END

PRINT 'End C2'
DROP TABLE #T 

9voto

Ruben Points 8393

Juste une intuition, mais normalement un HAUT-la COMMANDE nécessite SQL Server tampon, le résultat d'une certaine façon (soit l'indice analyse du résultat ou de l'ensemble de la suite dans un temp de la structure, ou quelque chose entre les deux).

On pourrait dire que pour les curseurs c'est aussi nécessaire, même lors de la commande par la clé primaire (comme dans votre exemple), que vous ne pouvez pas vous permettre un TOP 5 curseur de façon inattendue de retour de moins de 5 lignes lors de la sélection correspondante retourne exactement 5 lignes (ou pire: le curseur retourne plus de 5 lignes).

Cette étrange situation pourrait théoriquement se produire lorsqu'il y a des suppressions ou des inserts sur la table après l'analyse d'index de la gamme a déjà été déterminé pour le curseur, et les insertions/suppressions relèvent de l'analyse d'index de gamme, mais vous n'êtes pas encore fait l'extraction. Pour éviter cela, ils peuvent se tromper sur le côté sûr, ici. (Et ils n'optimisent pas pour #temp tables).

Une question cependant: est-SQL Server permettent à un FETCH FROM SELECT TOP n sans ORDER BY clause? (N'ai pas une instance de SQL Server en cours d'exécution ici.) Peut être intéressant de savoir quel plan que les causes.

1voto

Martin Smith Points 174101

Je suppose que d'y penser TOP N ne pouvait pas vraiment être efficacement mis en œuvre comme un curseur dynamique.

Les curseurs dynamiques de refléter toutes les modifications apportées aux lignes dans leur résultat définissez lorsque vous faites défiler le curseur. Les valeurs de données, de commande et de l'adhésion à l'lignes dans le résultat peut changer à chaque extraction.

donc, cela voudrait dire (en général, ignorant le #temp tableau aspect) que chaque extraction devra également déterminer si la ligne était encore en TOP N ou pas qui serait assez inefficace (besoin de compter à partir du haut de nouveau) ou ajouter de la complexité de mise en œuvre (besoin de suivre les modifications de données qui aurait une incidence sur l'appartenance) pour pas beaucoup de bénéfices.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X