O SQL Server estimou errado?
Olá Galera, boa noite!?
Hoje venho falar sobre um assunto que até agora pouco eu desconhecia, então decidir compartilhar esse conhecimento com a comunidade SQL Server.
Como de costume dedico esse post a um amigo e Super DBA SQL Server, Igor Antônio. O cara é um Guru de TI, tudo que perguntei ele soube me responder ele é um SQL Geek NATO.
Começando a “brincadeira”, A pergunta inicial é a seguinte: O que é melhor uma tabela temporária ou uma tabela variável? Na área de exatas e falando de SQL Server a resposta sempre vai ser DEPENDE..rs. Particularmente gosto muito de tabelas temporárias, mas, gostaria de falar aqui sobre uma diferença entre elas, um dos principais motivos que sempre utilizei as tabelas temporárias foi por causa das estatísticas que influenciam bastante no plano de execução. O que sempre ouvimos é que tabela variável sempre estima um registro, certo? ERRADO. Como assim Thiago?
Execute o script abaixo com o plano de execução habilitado (Ctrl + M)
USE tempdb
go
DECLARE @T TABLE (COD INT IDENTITY PRIMARY KEY CLUSTERED, VALOR INT NOT NULL)
INSERT INTO @T (VALOR) VALUES(1),(2),(3)
SELECT * FROM @T
Como o SQL Server estimou apenas uma linha, o otimizador de consulta pode estimar um plano ineficiente em caso de JOINs com outras tabelas e a primeira sugestão seria: mudar para uma tabela temporária. Porém, e possível fazer com que uma tabela variável estime mais que uma linha com a utilização do OPTION (RECOMPILE), será? Vamos novamente executar o script com o HINT e ver o resultado:
USE tempdb
go
DECLARE @T TABLE (COD INT IDENTITY PRIMARY KEY CLUSTERED, VALOR INT NOT NULL)
INSERT INTO @T(VALOR) VALUES(1),(2),(3)
SELECT * FROM @T OPTION (RECOMPILE)
Essa é nova pra mim Thiago? Confesso que pra mim também… O que aconteceu?
O SQL Server estima a quantidade de linhas que pode ser retornada em tempo de execução e sabe que na nossa tabela variável vai retornar três registros. Que dizer que toda vez que existir uma tabela variável em uma query sempre vou utilizar o hint? Galera sempre façam testes, pois, dependo da situação pode valer a pena ou não. Em um caso que você sabe que a tabela variável sempre vai retornar uma quantidade de registros exata para uma query o plano é “bom o suficiente” talvez seja uma boa que você paga menos recompilação ao contrário da tabela temporária, porém, isso é assunto para outro post.
Até mais espero que tenham gostado