Para os dados de exemplo...
/*Quick and dirty generation of some rows of data*/
SELECT value as [orderid],
1 as [custid],
1 as [empid],
1 as [shipperid],
getdate() as [orderdate],
'abcdefgh' as [filler]
INTO dbo.Orders
FROM generate_series(1,10000000)
CREATE CLUSTERED INDEX [idx_cl_od] ON [dbo].[Orders]
(
[orderdate] ASC
)
UPDATE STATISTICS dbo.Orders WITH FULLSCAN
E a seguinte consulta
SELECT [orderid], [custid], [empid], [shipperid], [orderdate], [filler]
FROM dbo.Orders
WHERE orderid <=7601715 AND 1=1 /*Prevent simple parameterisation*/
Então, na minha máquina de desenvolvimento (SQL Server 2022, DOP de 4), o custo de E/S da varredura de índice clusterizado é 46.8853
independente do plano serial ou paralelo. E o custo de CPU da varredura está 11.0002
no plano serial e 2.75004
no paralelo. Então, eu esperava que o ponto de inflexão entre os planos fosse quando o operador de paralelismo excedesse 8.25016
(um limite atingido quando as linhas estimadas que entram nele são em torno de 4,5 milhões). Na realidade, no ponto em que isso realmente ocorre, o custo para o operador de fluxos de coleta é 13.0501
(em torno de 3 milhões de linhas a mais do que eu esperava).
Se o SQL Server não estiver usando o custo geral do plano como ponto de inflexão, qual é a lógica real?
O ponto de inflexão é como você espera. As informações do showplan não refletem com precisão o custo do otimizador.
As duas primeiras consultas (paralela natural e serial hinted) têm um custo de 62,6855 na saída do otimizador.
O Showplan mostra um custo de 57,8855 para o plano serial (4,8 a menos).
A saída do otimizador para o plano serial tem um Filter acima do Scan. Este Filter é empurrado para baixo no Scan como um predicado residual (não SARG) por uma reescrita pós-otimização. A reescrita perde o custo do Filter.
Você pode ver o plano expandido (sem pushdown) usando o sinalizador de rastreamento 9130:
O Filtro tem um custo de 4,8.