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"
et le plan montre répété Extrait à partir de l'Analyse d'Index Cluster
à 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
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.
Question
- Quels critères de SQL Server à utiliser dans le choix d'une approche plutôt que l'autre?
- 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