SQL Server 2012 più lento del 2008


15

Ho migrato un sito Web e un database di grandi dimensioni da un server più vecchio (Windows 2008 / SQL Server 2008/16 GB RAM / 2 dischi Quad Core / SAS da 2,5 GHz) a un server più recente e molto migliore (Windows 2008 R2 / SQL Server 2012 SP1 / 64 GB RAM / 2 processori Core / 2 dischi SSD da 16 GHz).

Ho rimosso i file di database sul vecchio server, copiati e collegati al nuovo server. È andato tutto molto bene.

Successivamente, sono passato al livello di compatibilità a 110, ho aggiornato le statistiche, ricostruito gli indici.

Con mia grande delusione, ho notato che la maggior parte delle query sql sono molto più lente (2-3-4 volte più lente) sul nuovo server SQL 2012 rispetto al vecchio server SQL 2008.

Ad esempio, su una tabella con circa 700.000 record, sul vecchio server una query sull'indice ha richiesto circa 100 ms. Sul nuovo server, la stessa query richiede circa 350 ms.

Lo stesso accade per tutte le domande.

Gradirei un aiuto qui. Fammi sapere cosa controllare / verificare. Perché trovo molto difficile credere che su un server migliore con un SQL Server più recente, le prestazioni siano peggiori.

Più dettagli:

La memoria è impostata su max.

Ho questa tabella e indice:

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]

Ho eseguito questa query:

set statistics time on;
select summaryid, count(summaryid) from Answer_Details_23 group by summaryid order by count(summaryid) desc;
set statistics time off;

VECCHIO SERVER - Tempi di esecuzione di SQL Server: tempo CPU = 419 ms, tempo trascorso = 695 ms.

NUOVO SERVER - Tempi di esecuzione di SQL Server: tempo CPU = 1340 ms, tempo trascorso = 1636 ms.

PIANI DI ESECUZIONE caricati qui: http://we.tl/ARbPuvf9t8

Aggiornamento successivo:

  • I processori core AMD Opteron 16 da 2,1 GHz sembrano molto peggiori dei processori quad core Intel da 2,5 GHz
  • Grande miglioramento cambiando le opzioni di alimentazione di Windows da bilanciate ad alta potenza
  • Ulteriore miglioramento che modifica il grado massimo di parallelismo a 8 e la soglia di costo a 4

Ora, tempi di esecuzione di SQL Server: tempo CPU = 550 ms, tempo trascorso = 828 ms.

È ancora peggio del vecchio server, ma non è poi così male. Se hai altri suggerimenti (oltre alle ottimizzazioni di query locali), non esitare a commentare.


I commenti non sono per una discussione estesa; questa conversazione è stata spostata in chat .
Paul White Ripristina Monica

Risposte:


8

Ho avuto problemi simili con SQL Server, è possibile che il tuo server non sia configurato in modo ottimale. I nuovi Xeon sono dotati di TurboBoost, HT, ecc. Che possono influire in modo significativo sulle prestazioni del server.

Ad esempio, abbiamo avuto successo con; Configurazione a bassa latenza per server Dell

Le impostazioni saranno applicabili ai server non Dell, potrebbero avere nomi diversi.

Abbiamo anche migliorato le prestazioni impostando il profilo di gestione dell'alimentazione di Windows su alte prestazioni, da Bilanciato. Un'ultima cosa è che si consiglia di riservare fino a 8 GB di memoria per il sistema operativo su server x64, l'installazione SQL predefinita occupa tutta la memoria. Potrebbe essere utile provare la prenotazione di 4/8 GB impostando la configurazione massima della memoria di SQL Server su 4/8 GB in meno rispetto alla memoria totale.

La mia raccomandazione sarebbe di tornare al vecchio server, se possibile. Se non si dispone di script di regressione / automazione / caricamento disponibili, la cosa migliore da fare è registrare l'attività del sistema per 1-4 ore durante un periodo di alta attività. Quindi configurare un server Web uguale alla produzione e un computer client per eseguire lo script. Esegui la stessa attività sul nuovo server, apporta le modifiche alla configurazione ed esegui di nuovo la stessa attività. Davvero vorresti fare molto di più, ma non sembra che sarebbe praticabile ed è al di fuori dell'ambito di questa domanda.


Il carico non è così elevato sul server. SQL Server di solito si trova in 20-35 GB di memoria. In qualsiasi momento avevamo più di 16 GB di memoria libera. Inoltre, il processore non passa normalmente al 10-15% di utilizzo.
prog_sr08,

2
Il massimo miglioramento finora ottenuto impostando la gestione dell'alimentazione di Windows da bilanciata a elevata potenza. Quindi sembra davvero un problema con il processore. Tempi di esecuzione di SQL Server: tempo CPU = 892 ms, tempo trascorso = 874 ms.
prog_sr08,

8

Fammi sapere cosa controllare / verificare

Hai un problema di prestazioni. Seguire una metodologia di risoluzione dei problemi di prestazioni come Attese e Code per identificare il collo di bottiglia. La metodologia collegata mostra cosa misurare e come. Pubblica qui i risultati e possiamo aiutarti con consigli specifici basati sulle tue misurazioni effettive. Come è troppo aperto ed è supposizione di nessuno. Restringendolo a un problema specifico eliminerai le congetture.

Dopo l'aggiornamento

I piani sono abbastanza diversi. Il vecchio piano aveva un flusso aggregato basso nello stack che in realtà ha una cattiva stima della cardinalità (141k contro 108k) e la matematica hash ha ulteriormente frainteso, viceversa (35k contro 108k). Il nuovo piano non ha il flusso aggregato e ha stime accurate fino in cima. Ovviamente, questo non spiega perché il vecchio piano fosse in esecuzione più rapidamente .

Le scansioni inferiori hanno un numero di riga leggermente diverso (non significativo) ma costi piuttosto diversi: il vecchio è 2.49884 (IO 2.28979 CPU 0.20905) rispetto al nuovo 1.59109 (IO 1.53868 CPU 0.0524084). Ancora una volta indicherebbe una migliore esecuzione del 2012 (la ricostruzione dell'indice ha forse ridotto la frammentazione?).

Ciò che è molto diverso è il numero di thread: 32 in nuovi (ognuno con ~ 23k righe) contro 8 in vecchi (ognuno con ~ 95k righe). Il tavolo è piuttosto stretto. È possibile che il gran numero di thread stia effettivamente danneggiando le prestazioni a causa di invalidazioni della cache molto più frequenti . Proverei:

  1. eliminare HyperThreading nella nuova configurazione del server (se presente) e / o
  2. prova la query con un DOP 8.

Ho notato il tuo commento:

Aggiunto il piano di esecuzione con maxdop 8 Query è in realtà più veloce in questo modo

Probabilmente sono solo le CPU che si pestano a vicenda. Con gli SSD in atto, l'IO non è quasi nulla e la tabella è decisamente troppo piccola per garantire 32 scanner. Questo scambio di swap probabilmente sta invalidando costantemente L1 / L2.


1
Tutto è molto più lento nel 2012 rispetto al 2008. Non sto cercando di ottimizzare le query qui. Sarei felice di avere almeno le stesse prestazioni con lo stesso database esatto su questo nuovo server.
prog_sr08,

1
Le attese e le code non riguardano l'ottimizzazione delle query. Si tratta di identificare i colli di bottiglia.
Remus Rusanu,

Ho scaricato il documento. Sembra molto interessante Ci sto lavorando adesso, ma sembra che ci vorrà un po '. Puoi suggerire dove cercare prima?
prog_sr08

1
aspetta statistiche . ripristinarli sia sul 2008 che sul 2012, eseguire il carico per 5-10 minuti su entrambi, quindi confrontare le differenze tra il 2008 e il 2012.
Remus Rusanu,

Temo di non poter confrontare le statistiche tra i 2 server ora, perché il nuovo server ospita un sito / database live. Sul vecchio server è rimasto il database che non è più sotto carico.
prog_sr08,

3

Per la maggior parte dei moderni sistemi multi-core, e in particolare i sistemi multi-cpu, l'architettura hardware è tale che determinate porzioni di memoria sono lontane da determinati core / processori e alcune porzioni di memoria sono vicine a determinati core / processori. Questo è indicato come architettura di memoria non uniforme o NUMA in breve. Si desidera che l'impostazione MAXDOP corrisponda al numero di core per nodo NUMA per ridurre al minimo il numero di volte in cui un determinato nodo numa deve uscire dalla propria memoria per i dati.

È possibile utilizzare quanto segue per verificare la configurazione della nuova macchina e assicurarsi che MAXDOP sia impostato sulla migliore impostazione, dal punto di vista 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

Ho incluso @ServerRamInMBqui il parametro poiché lo uso per impostare le opzioni di configurazione Max Server Memorye Min Server Memorysu valori appropriati per il server specificato.


1
Ho 64 GB di RAM, 32 core del processore, 4 nodi numa. Ho impostato il grado massimo di parallelismo su 8 e la soglia di costo su 4. Con questa impostazione e con l'opzione di alimentazione impostata su potenza elevata, Tempi di esecuzione di SQL Server: tempo CPU = 550 ms, tempo trascorso = 828 ms.
prog_sr08,

Quindi è una vittoria, allora? Sono contento di vedere che funziona per te!
Max Vernon,

0

In quale versione e modalità di licenza ti trovi? Probabilmente non stai usando tutti i core. Vedi la nota in questa pagina - http://msdn.microsoft.com/en-us/library/ms143760.aspx

"Le licenze basate su Enterprise Edition con licenza Server + Client Access License (CAL) sono limitate a un massimo di 20 core per istanza di SQL Server."


2
Ciò si applicherebbe solo se avesse avuto CAL prima e nonno. Tuttavia, anche con solo 20 core, le prestazioni non dovrebbero calare sensibilmente sul precedente sistema (che ne aveva solo 8).
Aaron Bertrand

Ho la Web Edition (limitata a un numero inferiore di 4 socket o 16 core). Sul vecchio server avevo comunque solo 8 core.
prog_sr08,

0

Ho avuto lo stesso problema descritto in questa pagina: cambiare le impostazioni di potenza da "bilanciato" a "alte prestazioni" ha fatto una differenza drammatica, più che raddoppiando i tempi di risposta. Ora che stiamo usando SSD, non penso che il consumo di energia sia il problema che potrebbe essere stato.


-2

Ho anche affrontato questo problema per almeno 2 settimane senza alcuna soluzione solida piuttosto che confondere un problema con l'altro.

Infine la risoluzione come segue: -

  1. Ho ripristinato la compatibilità da 010 a 011

  2. Ripristina anche la compatibilità del database principale. Per impostazione predefinita, sql manterrà le impostazioni di compatibilità precedenti. Che dobbiamo cambiare manualmente.

Ti auguro il meglio

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.