Migrei um site e banco de dados grandes de um servidor mais antigo (Windows 2008 / SQL Server 2008/16 GB de RAM / 2 discos Quad Core / SAS de 2,5 GHz) para um servidor mais novo e muito melhor (Windows 2008 R2 / SQL Server 2012 SP1 / 64 GB RAM / 2 x 2,1 GHz 16 processadores / discos SSD).
Eu desanexei os arquivos de banco de dados no servidor antigo, copiei e os anexei no novo servidor. Tudo correu muito bem.
Depois disso, mudei para o nível de compatibilidade para 110, atualizei as estatísticas, recompile os índices.
Para minha grande decepção, notei que a maioria das consultas sql é muito mais lenta (2-3-4 vezes mais lenta) no novo servidor SQL 2012 do que no antigo servidor SQL 2008.
Por exemplo, em uma tabela com cerca de 700k registros, no servidor antigo, uma consulta no índice demorava cerca de 100ms. No novo servidor, a mesma consulta leva cerca de 350 ms.
O mesmo acontece para todas as consultas.
Gostaria muito de receber ajuda aqui. Deixe-me saber o que verificar / verificar. Porque acho muito difícil acreditar que, em um servidor melhor com um SQL Server mais recente, o desempenho seja pior.
Mais detalhes:
A memória está definida para máx.
Eu tenho esta tabela e índice:
CREATE TABLE [dbo].[Answer_Details_23](
[ID] [int] IDENTITY(1,1) NOT NULL,
[UserID] [int] NOT NULL,
[SurveyID] [int] NOT NULL,
[CustomerID] [int] NOT NULL default 0,
[SummaryID] [int] NOT NULL,
[QuestionID] [int] NOT NULL,
[RowID] [int] NOT NULL default 0,
[OptionID] [int] NOT NULL default 0,
[EnteredText] [ntext] NULL,
CONSTRAINT [Answer_Details_23_PK] PRIMARY KEY NONCLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
CREATE NONCLUSTERED INDEX [IDX_Answer_Details_23_SummaryID_QuestionID] ON [dbo].[Answer_Details_23]
(
[SummaryID] ASC,
[QuestionID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
Eu executei esta consulta:
set statistics time on;
select summaryid, count(summaryid) from Answer_Details_23 group by summaryid order by count(summaryid) desc;
set statistics time off;
SERVIDOR ANTIGO - Tempos de execução do SQL Server: tempo de CPU = 419 ms, tempo decorrido = 695 ms.
NOVO SERVIDOR - Tempos de execução do SQL Server: tempo de CPU = 1340 ms, tempo decorrido = 1636 ms.
PLANOS DE EXECUÇÃO carregados aqui: http://we.tl/ARbPuvf9t8
Atualização posterior:
- Os processadores AMD 2.1GHz Opteron 16 core parecem muito piores que os processadores quad core Intel 2.5GHz
- Grande melhoria, alterando as opções de energia do Windows, de balanceado para alta potência
- Melhoria adicional, alterando o grau máximo de paralelismo para 8 e o limite de custo para 4
Agora, tempos de execução do SQL Server: tempo de CPU = 550 ms, tempo decorrido = 828 ms.
Ainda é pior que o servidor antigo, mas não é tão ruim assim. Se você tiver outras sugestões (além das otimizações de consultas locais), não hesite em comentar.
fonte
Respostas:
Eu tive problemas semelhantes com o SQL Server, é possível que seu servidor não esteja configurado da melhor maneira. Xeons mais recentes vêm com TurboBoost, HT, etc., que podem afetar significativamente o desempenho do servidor.
Por exemplo, tivemos sucesso com; Configuração de baixa latência para servidores Dell
As configurações serão aplicáveis a servidores que não são da Dell; eles podem ter nomes diferentes.
Também aprimoramos o desempenho definindo o perfil de gerenciamento de energia do Windows como alto desempenho, da Balanced. Uma parte final é que é recomendável reservar até 8 GB de memória para o sistema operacional em servidores x64, a instalação padrão do SQL ocupa toda a memória. Convém tentar a reserva de 4 / 8GB definindo sua configuração de memória máxima do SQL Server como 4 / 8GB a menos que a memória total.
Minha recomendação seria reverter para o servidor antigo, se possível. Se você não possui scripts de regressão / automação / carregamento disponíveis, o melhor a fazer é registrar a atividade do sistema por 1 a 4 horas durante um período de alta atividade. Em seguida, configure um servidor da Web igual à produção e uma máquina cliente para executar o script. Execute a mesma atividade no novo servidor, faça a alteração na configuração e execute a mesma atividade novamente. Realmente você gostaria de fazer muito mais, mas não parece viável e está fora do escopo desta questão.
fonte
Você tem um problema de desempenho. Siga uma metodologia de solução de problemas de desempenho como Esperas e Filas para identificar o gargalo. A metodologia vinculada mostra o que medir e como. Publique aqui as conclusões e podemos ajudar com conselhos específicos com base nas suas medidas reais. Como está, é muito aberto e é uma incógnita. Reduzi-lo a um problema específico eliminará as suposições.
Após atualização
Os planos são bem diferentes. O plano antigo tinha um fluxo agregado baixo na pilha, que na verdade tinha uma estimativa de cardinalidade ruim (141k vs. 108k) e a matemática de hash imprevisível, pelo contrário (35k vs. 108k). O novo plano não possui o fluxo agregado e possui estimativas precisas até o topo. Obviamente, isso não explica por que o plano antigo estava sendo executado mais rapidamente .
As varreduras inferiores têm um número de linha ligeiramente diferente (não significativo), mas com custos bastante diferentes: o antigo é 2.49884 (CPU IO 2.28979 0.20205) versus o 1.59109 novo (CPU IO 1.53868 0.0524084). Mais uma vez, apontaria para uma melhor execução de 2012 (a reconstrução do índice talvez tenha reduzido a fragmentação?).
O que é muito diferente é o número de threads: 32 em novos (cada um com ~ 23k linhas) versus 8 em antigos (cada um com ~ 95k linhas). A mesa é bastante estreita. Ele poderia ser que o grande número de threads está realmente prejudicando o desempenho por causa de muito, muito mais frequente invalidations de cache . Eu tentaria:
Notou seu comentário:
Provavelmente são apenas CPUs pisando uns nos outros dedos. Com os SSDs instalados, o IO provavelmente não chega a nada e a mesa é definitivamente pequena demais para garantir 32 scanners. Essa troca de câmbio provavelmente está invalidando L1 / L2 constantemente.
fonte
Para a maioria dos sistemas modernos com vários núcleos, e particularmente os sistemas com várias CPUs, a arquitetura do hardware é tal que certas partes da memória estão distantes de certos núcleos / processadores e certas partes da memória estão próximas de certos núcleos / processadores. Isso é conhecido como Arquitetura de Memória Não Uniforme, ou NUMA, para abreviar. Você deseja que sua configuração MAXDOP corresponda ao número de núcleos por nó NUMA para minimizar o número de vezes que um determinado nó numa precisa sair da sua própria memória para obter dados.
Você pode usar o seguinte para verificar a configuração da sua nova máquina e garantir que o MAXDOP esteja definido com a melhor configuração, em termos de hardware :
Incluí o
@ServerRamInMB
parâmetro aqui, pois o uso para definir as opções de configuraçãoMax Server Memory
eMin Server Memory
para valores apropriados para o servidor especificado.fonte
Em que modo de edição e licenciamento você está? Você provavelmente não está usando todos os núcleos. Consulte a nota nesta página - http://msdn.microsoft.com/en-us/library/ms143760.aspx
"O Enterprise Edition com licenciamento baseado em Server + Client Access License (CAL) é limitado a um máximo de 20 núcleos por instância do SQL Server."
fonte
Eu tive o mesmo problema que o descrito nesta página: alternar as configurações de energia de "equilibrado" para "alto desempenho" fez uma diferença dramática - mais do que duplicando o tempo de resposta. Agora que estamos usando SSDs, não acho que o consumo de energia seja o problema que possa ter sido.
fonte
Também resolvi esse problema por pelo menos duas semanas sem nenhuma solução robusta, em vez de confundir um problema com o outro.
Finalmente, a resolução da seguinte forma:
Redefini a compatibilidade de 010 a 011
Redefina a compatibilidade do banco de dados mestre também. Por padrão, o sql manterá a configuração de compatibilidade antiga. Que precisamos mudar manualmente.
Muito bem sucedida
fonte