Esta situação vem “à berlinda” de vez em quando. A última vez onde vi esta questão aparecer foi num evento de profissionais de Data Platform.
O tamanho das variaveis não interessa, se eu colocar um varchar(max) ou varchar(50) é igual porque o SQL Server só usa o espaço que necessita.
Saltamos directamente para a parte interessante, a demo.
Criamos uma tabela e inserimos algumas linhas
create table DemoVarchar ( id int identity (1,1), ColunaVarcharMax varchar(max), ColunaVarchar50 varchar(50) ) go insert into DemoVarchar select '0123456789', '0123456789' from sys.objects a cross join sys.objects b
Temos então uma identity e duas colunas varchar com 10 caracteres cada.
select top 10 * from DemoVarchar
Fazemos agora duas queries “quase” iguais.
Na primeira queremos as colunas id e ColunaVarcharMax com o resultados ordenados pela id.
Na segunda apenas trocamos a ColunaVarcharMax pela ColunaVarchar50.
Vai ser tudo igual, não é?
Não esquecer de ligar o nosso SHOWPLAN.
select id, colunavarcharmax from DemoVarchar order by id select id, colunavarchar50 from DemoVarchar order by id
Dois planos “iguais”, apenas com uma diferença, o famoso triangulo amarelo na primeira query.
Vamos lá ver o que ele nos diz.
“ExcessiveGrant”. O SQL Server achou que precisaria de 80480 KB mas só usou 1416 KB.
Em comparação, na query em que usamos a ColunaVarchar50 os valores são bem diferentes.
Usou 1024 KB mas reservou só 3056 KB.
Não parece grande coisa. E de facto não é… enquanto tivermos duas colunas num select em que ordena 16129 linhas como é este caso. Quando forem mais colunas num dataset de 500 milhões tudo muda de figura. E como sabemos, o SQL Server espera por ter a memória para começar a query, o que leva a duas situações: por vezes fica à espera muito tempo por memória e consequentemente usa memória a mais o que leva a que outras queries não possam iniciar.
Só por exercício, será que se tivessemos um índice no id algo disto aconteceria?
create unique clustered index ucidx on DemoVarchar (id asc) select id, colunavarcharmax from DemoVarchar order by id select id, colunavarchar50 from DemoVarchar order by id
Como esperado o Sort desaparece, afinal a nossa tabela já está ordenada como precisamos.
E memória, precisamos?
Para as duas queries o resultado é o mesmo. Zero.
“O tamanho das variaveis não interessa, se eu colocar um varchar(max) ou varchar(50) é igual porque o SQL Server só usa o espaço que necessita”
Interessa. E muito.