Otimização: Movendo declarações de variáveis ​​para o topo do seu procedimento

15

Enquanto trabalhava na otimização de alguns procedimentos armazenados, sentei-me com o DBA e passei por alguns procedimentos armazenados com alto bloqueio e / ou alta atividade de leitura / gravação.

Uma coisa mencionada pelo DBA foi que eu deveria declarar todas as variáveis ​​(especialmente TABLEas) na parte superior do procedimento armazenado para evitar recompilações.

Esta é a primeira vez que ouvi isso e estava procurando alguma confirmação antes de revisar todos os diferentes procedimentos armazenados que temos. Ele estava chamando de "visualização tardia do código" e a recompilação estava bloqueando o esquema que seria responsável pelo bloqueio.

Mover todas as declarações de variáveis ​​para a parte superior do procedimento armazenado reduz as recompilações?

brad.v
fonte

Respostas:

18

Não.

Isso costumava ser verdade há muito tempo (e não é mais, pelo menos desde o SQL Server 2000), ou nunca era verdade e seu DBA apenas confundiu sua recomendação com a seguinte :

É importante agrupar todas as instruções DDL (como a criação de índices) para tabelas temporárias no início de um procedimento armazenado. Colocando essas instruções DDL juntas, compilações desnecessárias devido a alterações de esquema podem ser evitadas.

Você pode encontrar outra explicação sobre o raciocínio por trás desta recomendação nesta página .

Se dermos uma olhada neste Microsoft KB , verificamos que a causa de uma recompilação de procedimento armazenado pode ser uma das seguintes (SQL Server 2005+):

  1. Esquema alterado.
  2. Estatísticas alteradas.
  3. Recompile o DNR.
  4. Definir opção alterada.
  5. A tabela temporária foi alterada.
  6. Conjunto de linhas remoto alterado.
  7. Para permissões de navegação alteradas.
  8. O ambiente de notificação da consulta foi alterado.
  9. A visualização MPI foi alterada.
  10. As opções do cursor foram alteradas.
  11. Com opção de recompilação.

Declarar uma variável - mesmo uma variável de tabela (ie @table_variable) - não pode disparar nenhum desses eventos, obviamente, porque declarar uma variável não conta como DDL . Uma variável (mesmo uma variável de tabela) é um objeto temporário usado exclusivamente para sua programação T-SQL. É por isso que as variáveis ​​da tabela não obtêm estatísticas e não são vinculadas por transações . Declarar uma variável (tabela ou não) não pode acionar uma recompilação de proc.

Criar uma tabela temporária (ou seja #temp_table) ou um índice, no entanto, é DDL que afeta a definição física do banco de dados. Tabelas e índices temporários são objetos "reais" com estatísticas e controle transacional; portanto, criá-los pode disparar qualquer um dos eventos 1, 2 ou 5 da lista acima e, assim, acionar uma recompilação de proc.

Nick Chammas
fonte
3

Não deve fazer diferença, reduzir bloqueios de compilação ou causar menos recompilações para declarar uma variável na metade da pilha ou na parte superior. Por acaso, faço isso no topo para facilitar a leitura com mais freqüência.

Para chegar à parte da pergunta "o que é o meu pensamento do DBA", a única coisa que eu posso fazer (além do argumento de Nick de que eles estão pensando em como algo costumava ser) é que talvez eles estivessem falando sobre a detecção de parâmetros (consulte Opção 2 neste link em conversa simples)

Sobre seu bloqueio -> Se você estiver vendo um bloqueio real, esse não é o tipo de disputa de compilação sobre a qual o seu DBA está falando. Embora seja verdade que há certas coisas que afetam isso (não tabelas de qualificação de esquema, nem qualificações de esquema para suas chamadas de procedimento armazenado, por exemplo), essa não é a causa de suas altas leituras, certamente e provavelmente não a causa de seu bloqueio. Você definitivamente deve fazer tudo o que puder para evitar esses bloqueios de compilação. Mas eu consideraria o ajuste e a otimização do restante do código do procedimento armazenado uma tarefa mais importante do que me preocupar com a localização das variáveis. Você também pode ler Como identificar e resolver bloqueios de compilação, se quiser verificar se não está tendo problemas aqui.

Publique esses exemplos antes / depois e veremos o que o DBA está conduzindo aqui.

Mike Walsh
fonte