SQL Server 2012 mais lento que 2008

15

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.

prog_sr08
fonte
Comentários não são para discussão prolongada; esta conversa foi movida para o bate-papo .
Paul White Reinstate Monica

Respostas:

8

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.

AceCTO
fonte
A carga não é tão alta no servidor. O SQL Server geralmente fica em 20 a 35 GB de memória. A qualquer momento, tínhamos mais de 16 GB de memória livre. Além disso, o processador não passa normalmente de 10 a 15% de uso.
prog_sr08 27/02
2
Maior melhoria alcançada até agora ao definir o gerenciamento de energia do Windows de balanceado para alto consumo de energia. Por isso, parece realmente um problema no processador. Tempos de execução do SQL Server: tempo de CPU = 892 ms, tempo decorrido = 874 ms.
prog_sr08 28/02
8

Deixe-me saber o que verificar / verificar

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:

  1. eliminar HyperThreading na nova configuração do servidor (se houver) e / ou
  2. tente a consulta com um DOP 8.

Notou seu comentário:

O plano de execução adicionado com o maxdop 8 Query é realmente mais rápido dessa maneira

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.

Remus Rusanu
fonte
1
Tudo é muito mais lento em 2012 do que em 2008. Não estou tentando otimizar as consultas aqui. Eu ficaria feliz em ter pelo menos o mesmo desempenho com o mesmo banco de dados exato neste novo servidor.
prog_sr08 27/02
1
Esperas e filas não se trata de otimizar consultas. Trata-se de identificar gargalos.
Remus Rusanu 27/02
Eu baixei o documento. Parece muito interessante. Estou nisso agora, mas parece que vai demorar um pouco. Você pode sugerir onde procurar primeiro?
prog_sr08 27/02
1
aguarde estatísticas . redefini-las em 2008 e 2012, executar a carga por 5-10 minutos em ambos, diferenças, em seguida, comparar entre 2008 e 2012.
Remus Rusanu
Receio não poder comparar as estatísticas entre os dois servidores agora, porque o novo servidor hospeda um site / banco de dados ao vivo. No servidor antigo, permaneceu o banco de dados que não está mais carregado.
prog_sr08 27/02
3

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 :

DECLARE @CPUs int;
DECLARE @NumaNodes int;
DECLARE @ServerRAMInMB int;

SET @ServerRAMinMB = (SELECT (i.physical_memory_kb / 1024) AS ServerMemory 
    FROM sys.dm_os_sys_info i);
SET @CPUs = (SELECT i.cpu_count from sys.dm_os_sys_info i);
SET @NumaNodes = (SELECT MAX(c.memory_node_id) + 1 FROM sys.dm_os_memory_clerks c 
    WHERE memory_node_id < 64);

SELECT @ServerRamInMB, @CPUs, @NumaNodes;

IF @CPUs > 4 /* this would be 4 cores, not 4 CPUs */
BEGIN
    DECLARE @MaxDOP int;
    SET @MaxDOP = @CPUs * 0.75;
    IF @MaxDOP > (@CPUs / @NumaNodes) SET @MaxDOP = (@CPUs / @NumaNodes);
    EXEC sp_configure 'max degree of parallelism', @MaxDOP;
    EXEC sp_configure 'cost threshold for parallelism', 4; 
END

Incluí o @ServerRamInMBparâmetro aqui, pois o uso para definir as opções de configuração Max Server Memorye Min Server Memorypara valores apropriados para o servidor especificado.

Max Vernon
fonte
1
Tenho 64 GB de RAM, 32 núcleos de processador, 4 nós em uma. Defino o grau máximo de paralelismo como 8 e o limite de custo como 4. Com essa configuração e com a opção de energia definida como alta potência, Tempos de execução do SQL Server: tempo da CPU = 550 ms, tempo decorrido = 828 ms.
prog_sr08 28/02
Então isso é uma vitória, então? Fico feliz em ver que funciona para você!
Max Vernon
0

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."

Jeff Sacksteder
fonte
2
Isso só se aplicaria se ele tivesse CAL antes e tenha adquirido o avô. Mesmo com apenas 20 núcleos, o desempenho não deve cair visivelmente sobre o sistema anterior (que tinha apenas 8).
Aaron Bertrand
Eu tenho a Web Edition (limitada a menos de 4 soquetes ou 16 núcleos). No servidor antigo, eu tinha apenas 8 núcleos de qualquer maneira.
prog_sr08 27/02
0

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.

tom
fonte
-2

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:

  1. Redefini a compatibilidade de 010 a 011

  2. 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

Pramod Kumar PC
fonte