Esta é uma questão puramente acadêmica, tanto que não está causando problemas, e só estou interessado em ouvir explicações para o comportamento.
Faça uma edição padrão da tabela de registro CTE de junção cruzada Itzik Ben-Gan:
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
Emita uma consulta que criará uma tabela de número de 1 milhão de linhas:
SELECT
COUNT(N)
FROM
dbo.TallyTable(1000000) tt
Dê uma olhada no plano de execução paralelo para esta consulta:
Observe que a contagem de linhas 'real' antes do operador de coleta de fluxos é 1.004.588. Após o operador de fluxos de coleta, a contagem de linhas é a 1.000.000 esperada. Mais estranho ainda, o valor não é consistente e varia de uma corrida para outra. O resultado da COUNT está sempre correto.
Emita a consulta novamente, forçando o plano não paralelo:
SELECT
COUNT(N)
FROM
dbo.TallyTable(1000000) tt
OPTION (MAXDOP 1)
Desta vez, todos os operadores mostram as contagens de linha 'reais' corretas.
Eu tentei isso em 2005SP3 e 2008R2 até agora, os mesmos resultados em ambos. Alguma idéia sobre o que pode causar isso?
fonte