这是一个纯粹的学术问题,在很大程度上并没有引起问题,我只是想听听对此行为的任何解释。
取得标准的Itzik Ben-Gan交叉联接CTE理货表:
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
发出查询,该查询将创建一百万个行号表:
SELECT
COUNT(N)
FROM
dbo.TallyTable(1000000) tt
看一下此查询的并行执行计划:
请注意,“收集流”运算符之前的“实际”行计数为1,004,588。在集合流运算符之后,行数为预期的1,000,000。仍然是陌生人,该值不一致,并且每次运行都会有所不同。COUNT的结果始终正确。
再次发出查询,强制执行非并行计划:
SELECT
COUNT(N)
FROM
dbo.TallyTable(1000000) tt
OPTION (MAXDOP 1)
这次,所有运算符都显示正确的“实际”行数。
到目前为止,我已经在2005SP3和2008R2上进行了尝试,两者的结果相同。关于什么可能导致这种情况的任何想法?