Isto é o que eu aprendi até agora da minha pesquisa.
O .NET envia configurações de conexão que não são as mesmas que você obtém quando faz login no Management Studio. Aqui está o que você vê se farejar a conexão com o Sql Profiler:
-- network protocol: TCP/IP
set quoted_identifier off
set arithabort off
set numeric_roundabort off
set ansi_warnings on
set ansi_padding on
set ansi_nulls off
set concat_null_yields_null on
set cursor_close_on_commit off
set implicit_transactions off
set language us_english
set dateformat mdy
set datefirst 7
set transaction isolation level read committed
Agora estou colando essas configurações acima de cada consulta que executo quando estou logado no servidor sql, para garantir que as configurações sejam as mesmas.
Para este caso, tentei cada configuração individualmente, após desconectar e reconectar, e descobri que alterar arithabort de desligado para ligado reduzia a consulta do problema de 90 segundos para 1 segundo.
A explicação mais provável está relacionada ao sniffing de parâmetros, que é uma técnica que o Sql Server usa para escolher o que considera o plano de consulta mais eficaz. Quando você altera uma das configurações de conexão, o otimizador de consulta pode escolher um plano diferente e, nesse caso, aparentemente escolheu um plano ruim.
Mas não estou totalmente convencido disso. Eu tentei comparar os planos de consulta reais depois de alterar essa configuração e ainda não vi o diff mostrar nenhuma alteração.
Existe algo mais sobre a configuração arithabort que pode fazer com que uma consulta seja executada lentamente em alguns casos?
A solução parecia simples:basta colocar set arithabort na parte superior do procedimento armazenado. Mas isso pode levar ao problema oposto:alterar os parâmetros de consulta e, de repente, ele roda mais rápido com 'desligado' do que 'ligado'.
Por enquanto, estou executando o procedimento 'com recompilação' para garantir que o plano seja regenerado a cada vez. Tudo bem para este relatório em particular, já que leva talvez um segundo para recompilar, e isso não é muito perceptível em um relatório que leva de 1 a 10 segundos para retornar (é um monstro).
Mas não é uma opção para outras consultas que são executadas com muito mais frequência e precisam retornar o mais rápido possível, em apenas alguns milissegundos.