Se eu tiver a seguinte consulta no banco de dados Stack Overflow2010
UPDATE dbo.Posts
SET Title =
CASE
WHEN CreationDate <= '2008-01-01T00:00:00'
THEN 'A'
ELSE 'B'
END
FROM dbo.Posts
A saída resumida STATISTICS IO
está abaixo
Table 'Posts'. Scan count 1, logical reads 445699, physical reads 375822, page server reads 0, read-ahead reads 445521, page server read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob page server reads 0, lob read-ahead reads 0, lob page server read-ahead reads 0.
(1878895 rows affected)
e o plano de execução está aqui
Se eu criar uma tabela para armazenar o valor que desejo usar na minha comparação:
CREATE TABLE dbo.Canary
(
TheDate DATETIME
)
INSERT INTO dbo.Canary VALUES ('2008-01-01T00:00:00')
e então se eu alterar a consulta da seguinte forma:
UPDATE dbo.Posts
SET Title =
CASE
WHEN CreationDate <= Canary.TheDate
THEN 'A'
ELSE 'B'
END
FROM dbo.Posts
CROSS JOIN dbo.Canary
A saída STATISTICS IO é
Table 'Canary'. Scan count 1, logical reads 1, physical reads 1, page server reads 0, read-ahead reads 0, page server read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob page server reads 0, lob read-ahead reads 0, lob page server read-ahead reads 0.
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, page server reads 0, read-ahead reads 0, page server read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob page server reads 0, lob read-ahead reads 0, lob page server read-ahead reads 0.
Table 'Posts'. Scan count 1, logical reads 16787757, physical reads 3127, page server reads 0, read-ahead reads 784795, page server read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob page server reads 0, lob read-ahead reads 0, lob page server read-ahead reads 0.
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, page server reads 0, read-ahead reads 6291, page server read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob page server reads 0, lob read-ahead reads 0, lob page server read-ahead reads 0.
(1878895 rows affected)
e o plano de execução está aqui
Podemos ver que o número de leituras lógicas aumentou massivamente, de 445k para 16m. Levei algum tempo para encontrar no plano de execução onde está a fonte disso, mas eu o rastreei usando a propriedade Estatísticas de E/S reais / Leituras lógicas reais e posso ver que as leituras extras estão no operador de atualização de índice clusterizado, também posso ver que esse operador agora tem um valor para Número real de linhas para todas as execuções, enquanto o plano para a primeira consulta não tem.
O que está acontecendo aqui? O que está acontecendo na atualização do índice clusterizado que está causando o aumento nas leituras?
Acredito que a consulta deve usar uma variável se esse padrão de "valor em uma tabela de configuração" for usado. No entanto, esta é uma consulta de um aplicativo de fornecedor, então quero dar um feedback sobre o que está acontecendo como resultado da consulta ter sido escrita da maneira que foi.