Когда будет У курсора FAST_FORWARD есть рабочая таблица (и следует ли этого избегать)?

Предпосылки

Во время экспериментов с выполнением общих запросов я заметил, что иногда в предполагаемом плане отображается просто «Запрос на выборку»

Fetch

, а в фактическом плане - повторяющиеся выборки из сканирования кластеризованного индекса

Fetch Scan

на других случаи (например, при добавлении TOP в запрос) t В оценочном плане показан этап «запроса заполнения», который заполняет рабочую таблицу

Fetch and Populate

. Фактический план показывает сканирование кластерного индекса для заполнения рабочей таблицы с последующим повторным поиском по этой рабочей таблице.

Seeks

Вопрос

  1. Какие критерии использует SQL Server при выборе одного подхода перед другим?
  2. Прав ли я, полагая, что первый метод (без дополнительного шага заполнения рабочей таблицы) более эффективен?

(Дополнительный вопрос: если бы кто-нибудь мог объяснить, почему каждое сканирование в первом запросе считается за 2 логических чтения, это тоже может быть весьма поучительным)

Дополнительная информация

Я нашел эту статью здесь , в которой объясняется, что Курсоры FAST_FORWARD могут использовать динамический или статический план. Первый запрос в этом случае использует динамический план, а второй - статический.

Я также обнаружил, что если я попробую

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

, курсор будет неявно преобразован в курсор набора ключей , поэтому ясно, что конструкция TOP не поддерживается для динамических курсоров. , возможно, по причинам в ответе Рубена - все еще ищу окончательное объяснение этого.

Однако я также читал, что динамические курсоры обычно медленнее , чем их статические аналоги ( источник 1 , источник 2 ), что кажется мне удивительным, учитывая что статическая разновидность должна читать исходные данные, копировать их, а затем читать копию, а не просто читать исходные данные. В статье, на которую я ссылался ранее , упоминается, что динамические курсоры используют маркеры . Кто-нибудь может объяснить, что это такое? Это просто RID, ключ CI или что-то другое?

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 
31
задан Martin Smith 29 October 2011 в 19:40
поделиться