A consulta é uma única seleção que contém muitos níveis de agrupamento e agrega operações. Com SET ARITHABORT ON, leva menos de um segundo, caso contrário, leva vários minutos. Vimos esse comportamento no SQL Server 2000 e 2008.
A consulta é uma única seleção que contém muitos níveis de agrupamento e agrega operações. Com SET ARITHABORT ON, leva menos de um segundo, caso contrário, leva vários minutos. Vimos esse comportamento no SQL Server 2000 e 2008.
Respostas:
Um pouco datado, mas para quem acaba aqui com um problema semelhante ...
Eu tive o mesmo problema. Para mim, acabou sendo um farejamento de parâmetros, que no começo eu não entendia o suficiente para me preocupar. Adicionei um 'set arithabort on' que resolveu o problema, mas depois ele voltou. Então eu li:
http://www.sommarskog.se/query-plan-mysteries.html
Tudo esclareceu tudo. Como estava usando o Linq to SQL e tinha opções limitadas para corrigir o problema, acabei usando um guia de plano de consulta (consulte o final do link) para forçar o plano de consulta desejado.
Aplicativos .NET se conectam com a opção desabilitada por padrão, mas é habilitada por padrão no Management Studio. O resultado é que o servidor realmente armazena em cache 2 planos de execução separados para a maioria / todos os procedimentos. Isso afeta a maneira como o servidor executa cálculos numéricos e, como tal, você pode obter resultados muito diferentes, dependendo do procedimento. Essa é realmente apenas uma das 2 maneiras comuns pelas quais um processo pode receber um plano de execução terrível, sendo a outra a detecção de parâmetros.
Dê uma olhada em https://web.archive.org/web/20150315031719/http://sqladvice.com/blogs/gstark/archive/2008/02/12/Arithabort-Option-Eption-Effects-Stored-Procedure-Performance. aspx para um pouco mais de discussão sobre isso.
SET
opção, obter um plano melhor e diagnosticar isso como sendo a própria opção que está com falha. Não estou convencido de que o cara no seu link não tenha feito isso.
Eu argumentaria que isso era quase certamente um farejamento de parâmetros.
Afirma-se frequentemente que isso SET OPTIONS
pode afetar o desempenho dessa maneira, mas ainda tenho que ver uma única fonte autorizada para essa reivindicação, exceto no caso em que você está usando Visualizações indexadas / colunas computadas persistentes.
Nesse caso (para SQL2005 + e a menos que seu banco de dados esteja no modo de compatibilidade com SQL2000 ). Se você tiver os dois ARITHABORT
e, em ANSI_WARNINGS
OFF
seguida, descobrirá que o índice não está sendo usado, pode haver uma varredura em vez da busca desejada (e algumas despesas gerais, pois o resultado do cálculo persistente não pode ser usado). O ADO.NET parece ter como padrão ANSI_WARNINGS ON
um teste rápido que acabei de fazer.
A alegação na resposta de Ben de que "a maneira como o servidor executa cálculos numéricos" pode adicionar minutos a um resultado que, de outra forma, levaria menos de um segundo, não me parece credível. Acho que o que costuma acontecer é que, ao investigar um problema de desempenho, o Profiler é usado para identificar a consulta incorreta. Isso é colado no estúdio de gerenciamento e é executado e retorna resultados instantaneamente. A única diferença aparente entre as conexões é a ARITH_ABORT
opção.
Um teste rápido em uma janela do estúdio de gerenciamento mostra que quando SET ARITHABORT OFF
é ativada e a consulta é executada, o problema de desempenho se repete e, aparentemente, o caso está encerrado. Na verdade, essa parece ser a metodologia de solução de problemas usada no link Gregg Stark .
No entanto, isso ignora o fato de que, com essa opção definida, você pode obter o mesmo plano incorreto do cache .
Essa reutilização do plano pode ocorrer mesmo se você estiver conectado como um usuário diferente do que a conexão do aplicativo usa.
Eu testei isso executando uma consulta de teste primeiro em um aplicativo Web e depois no estúdio de gerenciamento com SET ARITHABORT OFF
e pude ver as contas de usuário subindo na consulta abaixo.
SELECT usecounts, cacheobjtype, objtype, text ,query_plan
FROM sys.dm_exec_cached_plans
CROSS APPLY sys.dm_exec_sql_text(plan_handle)
CROSS APPLY sys.dm_exec_query_plan(plan_handle)
Para que esse compartilhamento pf ocorra, todas as chaves de cache do plano devem ser iguais. Além de arithabort
outros exemplos, os usuários em execução precisam do mesmo esquema padrão (se a consulta depender da resolução implícita de nomes) e as conexões precisam do mesmo language
conjunto.
Sei que estou atrasado para esta festa, mas para futuros visitantes, Martin está exatamente correto. Corremos para o mesmo problema - um SP estava sendo executado muito lentamente para clientes .NET, enquanto era rápido para o SSMS. Ao explorar e resolver o problema, fizemos os testes sistemáticos sobre os quais Kenny Evitt pergunta em seu comentário à pergunta de Martin.
Usando uma variante da consulta de Martin, procurei o SP no cache do procedimento e encontrei dois deles. Olhando para os planos, era de fato um com o ARITHABORT ON e outro com o ARITHABORT OFF. A versão ARITHABORT OFF teve uma busca de índice, enquanto a versão ARITHABORT ON usou uma varredura de índice para a mesma saída. Dados os parâmetros envolvidos, a busca do índice exigiria uma pesquisa em dezenas de milhões de registros para a saída.
Limpei os dois procedimentos do cache e o cliente .NET executou o SP novamente, usando os mesmos parâmetros (que apresentavam um amplo intervalo de datas para um cliente com muita atividade). O SP voltou instantaneamente. O plano em cache usava a mesma varredura de índice anteriormente apresentada no plano ARITHABORT ON - mas desta vez o plano era para ARITHABORT OFF. Executamos o SP com os mesmos parâmetros no SSMS e, novamente, obtivemos resultados instantaneamente. Agora vimos que um segundo plano foi armazenado em cache, para ARITHABORT ON, com a varredura de índice.
Em seguida, limpamos o cache, executamos o SP no SSMS com um intervalo de datas restrito e obtivemos um resultado instantâneo. Descobrimos que o plano em cache resultante tinha uma busca de índice, pois a mesma saída foi tratada anteriormente com uma varredura (que também era uma busca no plano original com ARITHABORT OFF). Novamente no SSMS, executamos o SP, desta vez com o mesmo amplo intervalo de datas e vimos o mesmo desempenho terrível que tivemos na solicitação .NET original.
Em suma, a disparidade não tinha nada a ver com o valor real do ARITHABORT - com ele ligado ou desligado, de qualquer cliente, poderíamos obter um desempenho aceitável ou terrível: o que importava eram os valores dos parâmetros usados na compilação e no cache do plano.
Embora o MSDN indique que o próprio ARITHABORT OFF pode ter um impacto negativo na otimização de consultas, nossos testes confirmam que Martin está correto - a causa foi a detecção de parâmetros e o plano resultante não é o ideal para todos os intervalos de parâmetros.
Setting ARITHABORT to OFF can negatively impact query optimization leading to performance issues.
significa. Se eles estão apenas falando sobre incapacidade de usar índices em colunas e visualizações computadas (se ANSI_WARNINGS
também estiver desativada) ou se realmente têm algum outro efeito.
Só tive esse problema. Como as pessoas disseram aqui, a causa raiz é vários planos de consulta, um dos quais é subótimo. Eu só queria verificar se o ARITHABORT pode realmente causar o problema por si só (como a consulta com a qual eu estava tendo problemas não tinha parâmetros, o que tira o farejamento de parâmetros da equação).
Isso me lembra exatamente o mesmo problema que experimentei nos dias sql server 2008. No nosso caso, descobrimos repentinamente um trabalho sql abrandando repentinamente (geralmente alguns segundos e agora mais de 9 minutos), o trabalho precisa acessar um servidor vinculado, adicionamos o conjunto ARITHABORT na etapa do trabalho e parecia o problema foi resolvido por alguns dias e depois retornou.
Posteriormente, abrimos um ticket com suporte da MS e, inicialmente, eles também não puderam descobrir, e o ticket foi escalado para uma equipe de PFE muito sênior, e dois PFEs de suporte tentaram descobrir esse problema.
O motivo final é que a credencial do usuário (para executar a etapa da tarefa) não pode acessar as estatísticas das tabelas subjacentes (no lado do servidor vinculado) e, portanto, o plano de execução não é otimizado.
Em detalhes, o usuário não tem permissão no DBCC SHOW_STATISTICS (embora o usuário possa SELECT da tabela). De acordo com o MSDN , essa regra de permissão é alterada após o sql 2012 SP1
Permissões para o SQL Server e o banco de dados SQL
Para visualizar o objeto de estatísticas, o usuário deve possuir a tabela ou ser membro da função de servidor fixa sysadmin, da função de banco de dados fixa db_owner ou da função de banco de dados fixa db_ddladmin.
O SQL Server 2012 SP1 modifica as restrições de permissão e permite que os usuários com permissão SELECT usem esse comando. Observe que existem os seguintes requisitos para que as permissões SELECT sejam suficientes para executar o comando:
Para verificar esse problema, precisamos apenas executar o criador de perfil na instância vinculada do servidor e ativar alguns eventos na seção "Erros e avisos", como mostrado abaixo.
Espero que essa experiência possa ajudar a comunidade de alguma forma.