Pergunta

Eu tenho um procedimento armazenado que aceita uma entrada de data que é depois ajustado para a data atual se nenhum valor é passado em:

CREATE PROCEDURE MyProc
    @MyDate DATETIME = NULL
AS
    IF @MyDate IS NULL SET @MyDate = CURRENT_TIMESTAMP
    -- Do Something using @MyDate

Estou tendo problemas em que se @MyDate é passado como NULL quando o procedimento armazenado é compilado pela primeira vez, o desempenho é sempre terrível para todos os valores de entrada (NULL ou de outra forma), wheras se uma data / a data atual é passado desempenho quando o procedimento armazenado é compilado é bom para todos os valores de entrada (NULL ou de outra forma).

O que também é confuso é que o plano de execução pobre que é gerado no é terrível mesmo quando o valor de @MyDate usado é realmente NULL (e não definida para CURRENT_TIMESTAMP pela IF)

Eu descobri que a desativação parâmetro sniffing (por falsificação do parâmetro) fixa o meu problema:

CREATE PROCEDURE MyProc
    @MyDate DATETIME = NULL
AS
    DECLARE @MyDate_Copy DATETIME
    SET @MyDate_Copy = @MyDate
    IF @MyDate_Copy IS NULL SET @MyDate_Copy = CURRENT_TIMESTAMP
    -- Do Something using @MyDate_Copy

Eu sei que isso é algo a ver com o parâmetro sniffing, mas todos os exemplos que eu vi de "parâmetro sniffing mau ido" envolveram o procedimento armazenado a ser compilado com um parâmetro de não-representativa passada, no entanto aqui eu' m vendo que o plano de execução é terrível para todos os valores possíveis que servidor SQL pode pensar que o parâmetro pode levar no ponto em que a instrução é executada -. NULL, CURRENT_TIMESTAMP ou não

Alguém tem qualquer visão sobre por que isso está acontecendo?

Foi útil?

Solução

Basicamente sim - parâmetro sniffing (em alguns níveis de correção de) SQL Server 2005 está mal quebrado. Eu vi os planos que efetivamente nunca mais completo (em poucas horas em um pequeno conjunto de dados) mesmo para pequenas (alguns milhares de linhas) conjuntos de dados, que completa em segundos uma vez que os parâmetros são mascarados. E esta é nos casos em que o parâmetro tem sido sempre o mesmo número. Gostaria de acrescentar que, ao mesmo tempo eu estava lidando com isso, eu encontrei um monte de problemas com LEFT JOIN / nulos não completar e eu substituí-los com NOT IN existe ou não e isso resolveu o plano para algo que iria completar. Novamente, uma (muito fraco) emissão plano de execução. Na época, eu estava lidando com isso, os DBAs não me daria acesso SHOWPLAN, e desde que eu comecei mascarando todos os parâmetros SP, eu não tive quaisquer problemas plano de execução onde eu teria que cavar para isso por não conclusão .

No SQL Server 2008, você pode usar OPTIMIZE FOR UNKNOWN.

Outras dicas

Uma maneira que eu era capaz de contornar este problema em (SQL Server 2005) em vez de apenas mascarar os parâmetros redeclarando parâmetros locais foi adicionar consulta sugestões de optimização.

Aqui está um bom blog post que fala mais sobre isso: Parâmetro Sniffing em SqlServer 2005

eu usei: OPÇÃO (optimizar para (@p = '-1'))

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