Pergunta

Eu entendo que a opção forças com recompilar o otimizador para reconstruir o plano de consulta para procedimentos armazenados, mas quando você quer que isso aconteça?

Quais são algumas regras de ouro sobre quando usar a opção WITH RECOMPILE e quando não?

O que é a sobrecarga eficaz associado com apenas colocá-lo em cada sproc?

Foi útil?

Solução

Como já foi dito, você não deseja incluir simplesmente WITH RECOMPILE em cada proc armazenado como uma questão de hábito. Ao fazer isso, você estaria eliminando um dos principais benefícios de procedimentos armazenados: o fato de que ele salva o plano de consulta.

Por que é que, potencialmente, um grande negócio? Calculando um plano de consulta é muito mais intensa do que a compilação de código de procedimento regular. Porque a sintaxe de uma instrução SQL somente especifica o que você quer, e não (geralmente) como para obtê-lo, que permite que o banco de dados de um amplo grau de flexibilidade ao criar o físico plano (ou seja, as instruções passo-a-passo para realmente reunir e modificar dados). Há lotes de "truques" a consulta de banco de dados pré-processador pode fazer e escolhas que podem fazer - que ordem para unir as tabelas, as quais índices para uso, seja para aplicar cláusulas WHERE antes ou depois junta-se, etc.

Para uma instrução SELECT simples, pode não fazer a diferença, mas para qualquer consulta não-trivial, o banco de dados vai passar algum tempo sério (medido em milissegundos, em oposição aos microssegundos habituais) para chegar a uma plano óptimo. Para consultas realmente complexas, não podem mesmo garantir uma ideal plano, tem que apenas heurísticas de uso para chegar a um muito bom plano. Então, forçando-o para recompilar cada vez, você está dizendo que ele tem que passar por esse processo uma e outra vez, mesmo se o plano ficou antes era perfeitamente bom.

Dependendo do fornecedor, deve haver gatilhos automáticos para recompilar planos de consulta - por exemplo, se as estatísticas sobre uma mudança tabela significativamente (como, o histograma de valores de uma determinada coluna começa uniformemente distribuída por ao longo do tempo torna-se altamente enviesada ), então o DB deve perceber que e recompilar o plano. Mas de modo geral, os implementadores de um banco de dados vão ser mais inteligentes sobre que, no conjunto do que você é.

Tal como acontece com qualquer coisa relacionada desempenho, não tome tiros no escuro; descobrir quais são os gargalos que estão custando 90% do seu desempenho, e resolvê-los em primeiro lugar.

Outras dicas

Colocá-lo em cada procedimento armazenado não é uma boa idéia, porque a compilação de um plano de consulta é uma operação relativamente caro e você não vai ver qualquer benefício a partir dos planos de consulta que está sendo armazenada em cache e reutilizados.

O caso de um processo dinâmico onde cláusula construiu-se dentro de um procedimento armazenado pode ser tratado usando sp_executesql para executar o TSQL em vez de adicionar WITH RECOMPILE para o procedimento armazenado.

Outra solução (SQL Server 2005 em diante) é a utilização de dica com parâmetros específicos usando a dica OPTIMIZE FOR. Isso funciona bem se os valores nas linhas são estáticas.

SQL Server 2008 introduziu uma recurso pouco conhecido chamado "OPTIMIZE FOR UNKNOWN":

Esta dica direciona o otimizador de consulta para usar os algoritmos padrão que tem sempre usado se há valores dos parâmetros tinha sido passado para a consulta em tudo. Neste caso, o otimizador vai olhar em todos os dados estatísticos disponíveis para chegar a uma determinação do que o valores das variáveis ??locais utilizados para gerar o queryplan deve ser, em vez de olhar para o específico os valores dos parâmetros que foram passados ??para a consulta pela aplicação.

O uso mais comum é quando você pode ter uma cláusula WHERE dinâmica em um procedimento ... você não iria querer que o plano consulta específica para se compilado e guardado para execuções subseqüentes porque ele muito bem pode não ser a mesma cláusula exata da próxima vez que o procedimento é chamado.

geralmente uma alternativa melhor muito a WITH RECOMPILE é OPTION(RECOMPILE) como você pode ver na explicação abaixo, retirado a resposta desta questão aqui

Quando um problema parâmetro de sensibilidade é encontrado, um pedaço comum de conselhos sobre fóruns e sites de perguntas e respostas é "recompilação uso" (assumindo que o outras opções de ajuste apresentados anteriormente são inadequados). Infelizmente, esse conselho é muitas vezes mal interpretada para significar a adição WITH RECOMPILE opção para o procedimento armazenado.

Usando WITH RECOMPILE efetivamente nos leva de volta para o SQL Server 2000 comportamento, onde o procedimento armazenado inteiro é recompilados em cada execução. A melhor alternativa, no SQL Server 2005 e, mais tarde, é Use a opção (RECOMPILE) dica de consulta apenas na declaração de que sofre com o problema farejadores de parâmetro. Esta consulta dica resultados em uma recompilação de apenas a declaração problemática; planos de execução para outras instruções dentro do procedimento armazenado são armazenados em cache e reutilizada como normal.

Usando WITH RECOMPILE também significa o plano compilado para o armazenadas procedimento não está em cache. Como resultado, nenhuma informação de desempenho é mantida em DMVs tais como sys.dm_exec_query_stats. Usando a consulta dica em vez significa que um plano compilado pode ser armazenado em cache e desempenho informação está disponível nos DMVs (embora seja limitado ao mais execução recente, para a instrução afetada apenas).

Para instâncias em execução pelo menos SQL Server 2008 compilação 2746 (Service Pack 1 com atualização cumulativa 5), ??usando OPÇÃO (RECOMPILE) tem outra vantagem significativa sobre WITH RECOMPILE: única opção (RECOMPILE) permite que o parâmetro Embedding Optimization.

Ele só deve ser usado quando testar com dados reprentative e contexto demonstram que fazer sem produz planos de consulta inválido (o que quer que as possíveis razões pode ser). Não supor de antemão (sem testar) que um SP não vai otimizar corretamente.

A única excepção para invocação manual só (ou seja, não codificá-lo no SP): Quando você sabe que você já alterou substancialmente o caráter das tabelas de destino. por exemplo. TRUNCATE, cargas a granel, etc.

É mais uma oportunidade para a otimização prematura.

Nota: Eu tenho uma abundância de pontos. Se um newby submete a mesma resposta abaixo, e você concorda, upvote deles.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top