Desempenho do plano de execução do procedimento armazenado fraco do SQL - sniffing de parâmetro
Eu tenho um procedimento armazenado que aceita uma entrada de data que é definida posteriormente para a data atual se nenhum valor for passado:
<code>CREATE PROCEDURE MyProc @MyDate DATETIME = NULL AS IF @MyDate IS NULL SET @MyDate = CURRENT_TIMESTAMP -- Do Something using @MyDate </code>
Estou tendo problemas em que se@MyDate
é passado comoNULL
Quando o procedimento armazenado é compilado pela primeira vez, o desempenho é sempre terrível para todos os valores de entrada (NULL
ou de outra forma), onde se uma data / a data atual é passada quando o procedimento armazenado é compilado, o desempenho é bom para todos os valores de entrada (NULL
ou então).
O que também é confuso é que o plano de execução ruim gerado é terrível mesmo quando o valor de @MyDate usado éna realidade NULL
(e não definido paraCURRENT_TIMESTAMP
pela declaração IF)
Descobri que desabilitar o sniffing de parâmetro (falsificando o parâmetro) corrige meu problema:
<code>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 </code>
Eu sei que isso é algo a ver com o sniffing de parâmetro, mas todos os exemplos que vi de "parâmetro sniffing gone bad" envolveram o procedimento armazenado sendo compilado com um parâmetro não representativo passado, no entanto, aqui estou vendo que o plano de execução é péssimo para todos os valores concebíveis que o SQL Server possa achar que o parâmetro pode levar no ponto em que a instrução é executada -NULL
, CURRENT_TIMESTAMP
ou então.
Alguém tem alguma idéia de por que isso está acontecendo?