To jest pytanie czysto akademickie, o tyle, że nie powoduje problemu, a ja po prostu chcę usłyszeć wyjaśnienia tego zachowania.
Weźmy standardowy numer tabeli wyników CTE Itzika Ben-Gana:
USE [master]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[TallyTable]
(
@N INT
)
RETURNS TABLE WITH SCHEMABINDING AS
RETURN
(
WITH
E1(N) AS
(
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1
) -- 1*10^1 or 10 rows
, E2(N) AS (SELECT 1 FROM E1 a, E1 b) -- 1*10^2 or 100 rows
, E4(N) AS (SELECT 1 FROM E2 a, E2 b) -- 1*10^4 or 10,000 rows
, E8(N) AS (SELECT 1 FROM E4 a, E4 b) -- 1*10^8 or 100,000,000 rows
SELECT TOP (@N) ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS N FROM E8
)
GO
Wydaj zapytanie, które utworzy 1 milionową tabelę numerów wierszy:
SELECT
COUNT(N)
FROM
dbo.TallyTable(1000000) tt
Spójrz na równoległy plan wykonania dla tego zapytania:
Należy zauważyć, że „rzeczywista” liczba wierszy przed operatorem zbierania strumieni wynosi 1 004 588. Po operatorze zbierania strumieni liczba przewidywanych wierszy wynosi 1 000 000. Co dziwniejsze, wartość nie jest spójna i będzie się różnić w zależności od serii. Wynik COUNT jest zawsze poprawny.
Uruchom ponownie zapytanie, wymuszając plan nierównoległy:
SELECT
COUNT(N)
FROM
dbo.TallyTable(1000000) tt
OPTION (MAXDOP 1)
Tym razem wszyscy operatorzy pokazują prawidłowe „rzeczywiste” liczby wierszy.
Próbowałem tego do tej pory na 2005SP3 i 2008R2, takie same wyniki na obu. Wszelkie przemyślenia, co może to powodować?
źródło