Estou tentando otimizar a seguinte declaração:
'VI'+CAST(month(GETDATE()) AS NVARCHAR)+'/'+CAST(year(GETDATE()) AS NVARCHAR)
+'/00000' +CAST(@number+1 AS VARCHAR)
A instrução produz um valor como VI1/2011/000002
se o @number
parâmetro fosse 1
.
Eu gostaria de otimizar isso em termos de remoção de declarações de conversão redundantes e fornecer uma maneira eficiente de concatenar as strings e inteiros.
Nenhum atalho, não há concatenação elegante de strings no SQL Server
Você está misturando varchar e nvarchar: a precedência do tipo de dados significa que toda a expressão será nvarchar.
Se você estiver realizando essa conversão com frequência à medida que os dados são selecionados, tente usar um campo calculado persistente. Ele é adicionado à tabela e o SQL Server o calcula automaticamente sempre que os dados são inseridos ou atualizados. Você paga a penalidade de cálculo uma vez - apenas uma vez - e então é menos CPU sempre que os dados são selecionados de volta. Você pode até colocar um índice nele se estiver filtrando consultas com esse campo.
O SQL Server 2012 apresenta uma nova função que parece perfeitamente adequada às suas necessidades:
CONCAT()
.Aqui está um código de exemplo:
Dito isso, eu recomendo, pois outros devem fazer o trabalho de apresentação em sua camada de apresentação e não no banco de dados. Nos casos em que é mais fácil jogá-lo em sua consulta SQL existente, no entanto, acredito que
CONCAT()
será útil para você.Isso cobre o aspecto de programabilidade. Não sei o quão bem isso funcionaria, embora aposto que certamente não seria pior do que sua solução existente.
Para mais exemplos, dê uma olhada em:
Você não pode obter isso como um parâmetro e passá-lo para o SQL proc da camada de aplicativo, como .net ou java ou php...?
Seria muito mais simples não fazer isso no servidor SQL!
Como gbn sugere (esta resposta começou como um comentário em sua postagem, mas cresceu muito para ser prática nessa área), a única otimização simples óbvia é tornar esse VARCHAR um NVARCHAR e salvar uma conversão de tipo por invocação. Do jeito que você tem, haverá uma conversão explícita para VARCHAR seguida por uma conversão implícita para NVARCHAR. Ou faça os NVARCHARs VARCHARs se você quiser um VARCHAR no final de qualquer maneira.
Talvez você possa alterar o
CAST(month(GETDATE()) AS NVARCHAR)+'/'+CAST(year(GETDATE()) AS NVARCHAR)
para em vezCONVERT()
de um formato de string dat que incluamm/yyyy
e useSUBSTRING
para extrair essa parte. Dessa forma você tem:ao invés de
por invocação.
Mas realmente isso não vai economizar muito, se alguma coisa. Mesmo que salvasse alguma coisa em termos de carga da CPU ou tempo de relógio de parede, espero que seja muito pequeno, mesmo em um grande conjunto de resultados e/ou em um loop longo. E o formato não seria exatamente o mesmo: seu formato atual inclui
m/yy
(sem zero à esquerda para meses menores que 10) e isso renderiamm/yy
.Concorde com gbn em misturar nvarchar com varchar, uma maneira alternativa de tornar o sql mais fácil de ler (não torna a execução mais rápida/lenta), poderia ser:
vs
NOTA IMPORTANTE: Quando o mês é < 10 resultado diferente produzido: