Alguém é capaz de explicar algum comportamento que estou vendo com o SQL Profiler? Tomando os dois lotes a seguir:
exec sp_executesql N'
declare @t table (
x int
)
insert into @t (x) select top 10 number from dbo.gennumbers
select * from @t
union
select * from @t
'
exec sp_executesql N'
select top 10 number from dbo.gennumbers
union
select top 10 number from dbo.gennumbers
'
(isso é uma simplificação de algumas refatorações que estou fazendo; na realidade, a tabela temporária é preenchida por meio de um CTE que é reutilizado na consulta final, mitigando assim a quantidade de trabalho duplicado que o SQL Server precisa fazer ao armazenar os dados em cache).
Neste exemplo, GenNumbers é simplesmente uma tabela de números com uma única coluna que contém apenas uma sequência sequencial de números - nada de especial.
No profiler, estou obtendo os seguintes resultados:
Lote 1, com a tabela temporária:
Leituras de dados de texto do evento SP:StmtCompleted INSERT INTO(...) 27 SP:StmtCompleted SELECT * FROM ... 6 SQL:StmtCompleted exec sp_executesql 170
Lote 2, um golpe direto:
Leituras de dados de texto do evento SP:StmtCompleted SELECT TOP 10 * ... 6 SQL: StmtCompleted exec sp_executesql 6
O que estou tentando entender é a anomalia da contagem final de leitura no arquivo SQL:StmtCompleted
. Eu esperava que o total de leituras fosse igual à soma de todas as leituras que ocorrem no lote, mas não parece ser o caso no lote 1 - na verdade, é significativamente maior. Enquanto o lote 2, que faz uma única seleção, leituras finais == leituras reais.
Não há nada óbvio no plano de execução para ver para onde está indo esse tempo extra, mas talvez eu não esteja capturando a coisa certa - alguém tem alguma opinião sobre o que realmente está acontecendo? Estou me perguntando se preciso me preocupar com as 100 leituras extras que o SQL Server está "me dando", visto que essa contagem de leitura é cinco ou seis vezes maior do que a contagem real de leitura.
Presumo que seja algo relacionado ao SQL que precisa manter informações sobre a tabela temporária, mas não está claro exatamente o quê. Qualquer luz derramada seria útil.
Há um implícito
CREATE TABLE
no início eDROP TABLE @T
no final quando a tabela sai do escopo que não está associado à instruçãoINSERT
ou àSELECT
instrução.Se você substituir por uma
#temp
tabela, deverá ver algumas leituras adicionais para as instruçõesdrop
ecreate
. Para mim, vejo 36 para oCREATE
e 100 para o , oDROP
que representa 136 das 137 leituras que faltam.(Script com
#temp
tabela)