O ambiente:
Temos duas máquinas Windows Server 2003 R2 de 32 bits executando o SQL Server 2005. As configurações de hardware são servidores idênticos com CPU Xeon 5160, 4 GB de RAM e 13 GB de RAID0. Os sinalizadores AWE e / 3GB não estão ativados.
Os servidores foram configurados lado a lado usando uma lista de verificação de instalação predefinida e TODOS os softwares instalados são os mesmos nas duas máquinas.
Cada configuração de instalação do servidor SQL e nível de patch que sabemos verificar são idênticos. Uma diferença é que o TEMPDB tem 400 MB na máquina rápida e 1,2 GB na máquina lenta. No entanto, em ambos os casos, não vemos nenhuma alocação de TEMPDB ocorrendo.
O problema:
Há um procedimento armazenado que é executado em 2 segundos em um, mas 15 minutos no outro. Durante os 15 minutos adicionais, há pouca ou nenhuma atividade no disco, nenhum uso de memória é alterado, mas um núcleo da CPU é fixado em 100% o tempo todo.
Esse comportamento persiste mesmo quando o backup dos bancos de dados é feito de um e restaurado no outro.
Como é um procedimento armazenado, o monitor de atividade e o criador de perfil não nos mostram detalhes sobre onde está ocorrendo essa atividade de alta CPU no procedimento armazenado.
A questão:
O que mais devemos olhar?
Acompanhamento:
A lentidão ocorre nas instruções FETCH NEXT para a seguinte definição de cursor:
DECLARE C CURSOR FOR
SELECT X, Y
FROM dbo.A
WHERE X NOT IN (SELECT X FROM dbo.B)
AND Z <=0
...
<snip>
...
FETCH NEXT FROM C INTO @X, @Y
FETCH NEXT FROM C INTO @X, @Y
...
Cada uma das instruções FETCH - em uma tabela contendo apenas cerca de 1000 linhas - requer cerca de 7,25 minutos. (Não, eu não sei por que ele faz dois seguidos, preciso perguntar aos desenvolvedores, mas ele é executado corretamente nos dois servidores).
Desconfio um pouco desse "NOT IN (SELECT ...)", pois parece que o Virtual Reads é realmente alto.
fonte
Respostas:
Usando uma metodologia de solução de problemas de desempenho como Esperas e Filas, identifique o motivo do alto consumo de CPU, a ação apropriada poderá ser recomendada assim que o gargalo for identificado.
fonte
O SQL Server está escolhendo um plano diferente na outra caixa.
A restauração normalmente remove problemas com base em estatísticas, portanto, observei as diferenças do servidor.
Algumas verificações grosseiras primeiro. Não assuma: verifique
Então pule no fundo do poço, conforme a resposta de Remus.
fonte
Se todas as outras coisas forem iguais, é provável (conforme a resposta de @ gbn) que um plano de execução diferente esteja sendo gerado em cada servidor. Como um exercício acadêmico, seria interessante ver os dois planos, então pegue-os no cache do plano em cada servidor e adicione-os à sua pergunta, se possível. Podemos então identificar as diferenças nos planos que estão causando uma variação tão grande no desempenho.
Para uma solução rápida, consulte a dica USE PLAN . Isso torna possível anexar o bom plano do servidor rápido ao procedimento armazenado no servidor lento.
Edit: Após atualização re: cursor
Outra variação em sua consulta para tentar não ver mencionada em outras respostas:
fonte
Humor me, e tente substituir:
com isso:
Acho que isso não deve se manifestar como um problema de desempenho na parte FETCH NEXT FROM do seu código, mas ainda não tomei minha injeção de cafeína. Experimente minha sugestão e me avise.
Espero que isto ajude,
Matt
fonte
Verifique seus índices e atualize todas as suas estatísticas. Eu tive um problema muito simples e acabou que as estatísticas em uma máquina eram instáveis.
fonte
Eu experimentei esse mesmo comportamento duas vezes e vou lhe dizer o que o corrigiu toda vez:
1.) Adicionei a dica WITH RECOMPILE ao procedimento armazenado porque o plano em cache era terrível.
2.) Alterei o procedimento armazenado para usar tabelas temporárias em vez de variáveis de tabela.
Espero que qualquer uma dessas ajuda. Boa sorte.
fonte