SQL Server 2012 langsamer als 2008

15

Ich habe eine große Website und Datenbank von einem älteren Server (Windows 2008 / SQL Server 2008/16 GB RAM / 2 x 2,5 GHz Quad Core / SAS-Festplatten) auf einen neueren, viel besseren Server (Windows 2008 R2 / SQL Server 2012 SP1 / 64 GB RAM / 2 x 2,1 GHz (16 Core-Prozessoren / SSD-Festplatten).

Ich habe die Datenbankdateien vom alten Server getrennt, sie kopiert und auf dem neuen Server angehängt. Alles ist sehr gut gelaufen.

Danach wechselte ich zur Kompatibilitätsstufe 110, aktualisierte Statistiken, erstellte Indizes neu.

Zu meiner großen Enttäuschung stellte ich fest, dass die meisten SQL-Abfragen auf dem neuen SQL 2012-Server viel langsamer (2-3-4-mal langsamer) sind als auf dem alten SQL 2008-Server.

Beispiel: Bei einer Tabelle mit ca. 700.000 Datensätzen dauerte eine Indexabfrage auf dem alten Server ca. 100 ms. Auf dem neuen Server dauert dieselbe Abfrage ungefähr 350 ms.

Gleiches gilt für alle Abfragen.

Ich würde mich über Hilfe hier freuen. Lassen Sie mich wissen, was zu überprüfen ist. Da ich es kaum glauben kann, dass auf einem besseren Server mit einem neueren SQL Server die Leistung schlechter ist.

Mehr Details:

Der Speicher ist auf max.

Ich habe diese Tabelle und Index:

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]

Ich habe diese Abfrage ausgeführt:

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

ALTER SERVER - SQL Server-Ausführungszeiten: CPU-Zeit = 419 ms, verstrichene Zeit = 695 ms.

NEUER SERVER - SQL Server-Ausführungszeiten: CPU-Zeit = 1340 ms, verstrichene Zeit = 1636 ms.

AUSFÜHRUNGSPLÄNE, die hier hochgeladen wurden: http://we.tl/ARbPuvf9t8

Späteres Update:

  • AMD 2.1GHz Opteron 16 Core Prozessoren sehen viel schlechter aus als Intel 2.5GHz Quad Core Prozessoren
  • Große Verbesserung bei der Änderung der Windows-Energieoptionen von ausgewogen auf hohe Leistung
  • Weitere Verbesserung: Maximaler Parallelitätsgrad auf 8 und Kostenschwelle auf 4

Jetzt SQL Server-Ausführungszeiten: CPU-Zeit = 550 ms, verstrichene Zeit = 828 ms.

Es ist immer noch schlimmer als der alte Server, aber nicht so schlimm. Wenn Sie andere Vorschläge (außer Optimierungen für lokale Abfragen) haben, können Sie diese gerne kommentieren.

prog_sr08
quelle
Kommentare sind nicht für längere Diskussionen gedacht. Diese Unterhaltung wurde in den Chat verschoben .
Paul White Monica wieder einsetzen

Antworten:

8

Ich hatte ähnliche Probleme mit SQL Server. Möglicherweise ist Ihr Server nicht optimal konfiguriert. Neuere Xeons sind mit TurboBoost, HT usw. ausgestattet, die die Serverleistung erheblich beeinträchtigen können.

Zum Beispiel hatten wir Erfolg mit; Konfiguration mit geringer Latenz für Dell Server

Die Einstellungen gelten für Server, die nicht von Dell stammen. Möglicherweise haben sie unterschiedliche Namen.

Wir haben auch die Leistung verbessert, indem wir das Windows-Energieverwaltungsprofil von Balanced auf Hochleistung eingestellt haben. Als letztes wird empfohlen, bis zu 8 GB Arbeitsspeicher für das Betriebssystem auf x64-Servern zu reservieren. Die standardmäßige SQL-Installation beansprucht den gesamten Arbeitsspeicher. Möglicherweise möchten Sie eine 4/8-GB-Reservierung versuchen, indem Sie die maximale SQL Server-Speicherkonfiguration auf 4/8 GB weniger als den gesamten Speicher festlegen.

Meine Empfehlung wäre, wenn möglich auf den alten Server zurückzukehren. Wenn Sie keine Regressions- / Automatisierungs- / Ladeskripte zur Verfügung haben, können Sie Ihre Systemaktivität am besten 1-4 Stunden lang während eines Zeitraums mit hoher Aktivität aufzeichnen. Richten Sie dann einen Webserver wie in der Produktion und einen Client-Computer ein, auf dem das Skript ausgeführt wird. Führen Sie dieselbe Aktivität auf dem neuen Server aus, nehmen Sie die Konfigurationsänderungen vor und führen Sie dieselbe Aktivität erneut aus. Eigentlich würden Sie viel mehr tun wollen, aber es scheint nicht, dass es machbar wäre und außerhalb des Rahmens dieser Frage liegt.

AceCTO
quelle
Die Last auf dem Server ist nicht so hoch. SQL Server verfügt normalerweise über einen Arbeitsspeicher von 20 bis 35 GB. Zu jedem Zeitpunkt hatten wir mehr als 16 GB freien Speicher. Außerdem lässt der Prozessor normalerweise keine 10-15% -ige Auslastung zu.
prog_sr08
2
Größte Verbesserung, die bisher erzielt wurde, indem die Energieverwaltung von Windows von ausgeglichen auf hohe Leistung eingestellt wurde. Es sieht also wirklich nach einem Prozessorproblem aus. SQL Server-Ausführungszeiten: CPU-Zeit = 892 ms, verstrichene Zeit = 874 ms.
prog_sr08
8

Lassen Sie mich wissen, was zu überprüfen ist

Sie haben ein Leistungsproblem. Befolgen Sie eine Methode zur Fehlerbehebung bei der Leistung, z. B. Warteschlangen und Wartezeiten , um den Engpass zu ermitteln. Die verknüpfte Methodik zeigt Ihnen, was und wie zu messen ist. Veröffentlichen Sie hier die Ergebnisse und wir können Ihnen mit spezifischen Ratschlägen helfen, die auf Ihren tatsächlichen Messungen basieren. Wie es ist zu offen und ist jedermanns Vermutung. Durch Eingrenzen auf ein bestimmtes Problem wird das Rätselraten beseitigt.

Nach dem Update

Die Pläne sind ganz anders. Der alte Plan hatte ein Stream-Aggregat-Tief auf dem Stack, das tatsächlich eine schlechte Kardinalitätsschätzung (141.000 vs. 108.000) und die Hash-Mathematik weitere Fehlprognosen enthält (35.000 vs. 108.000). Der neue Plan verfügt nicht über das Stream-Aggregat und enthält genaue Schätzungen bis ganz nach oben. Dies erklärt natürlich nicht, warum der alte Plan schneller ausgeführt wurde .

Die unteren Scans haben eine geringfügig andere Zeilennummer (nicht signifikant), aber ganz andere Kosten: alt ist 2.49884 (IO 2.28979 CPU 0.20905) gegenüber neu 1.59109 (IO 1.53868 CPU 0.0524084). Auch dies würde auf eine bessere Ausführung für 2012 hindeuten (die Neuerstellung des Index hat möglicherweise die Fragmentierung verringert?).

Was sehr unterschiedlich ist, ist die Anzahl der Threads: 32 in new (jeder bekommt ~ 23k Zeilen) vs. 8 in old (jeder bekommt ~ 95k Zeilen). Der Tisch ist ziemlich eng. Es kann sein, dass die große Anzahl von Threads die Leistung beeinträchtigt, weil der Cache sehr viel häufiger ungültig wird . Ich würde versuchen:

  1. beseitigen Sie HyperThreading in der neuen Serverkonfiguration (falls vorhanden) und / oder
  2. versuchen Sie die Abfrage mit einem DOP 8.

Bemerkte Ihren Kommentar:

Fügte hinzu, dass der Ausführungsplan mit maxdop 8 Query auf diese Weise tatsächlich schneller ist

Es sind wahrscheinlich nur CPUs, die sich gegenseitig auf die Zehen treten. Mit vorhandenen SSDs ist die E / A wahrscheinlich so gut wie nichts, und die Tabelle ist definitiv zu klein, um 32 Scanner zu rechtfertigen. Dieser Austausch macht wahrscheinlich L1 / L2 ständig ungültig.

Remus Rusanu
quelle
1
2012 ist alles viel langsamer als 2008. Ich versuche hier nicht, die Abfragen zu optimieren. Ich würde mich freuen, auf diesem neuen Server mindestens die gleiche Leistung mit genau der gleichen Datenbank zu haben.
prog_sr08
1
Bei Wartezeiten und Warteschlangen geht es nicht um die Optimierung von Abfragen. Geht es darum, Engpässe zu identifizieren.
Remus Rusanu
Ich habe das Dokument heruntergeladen. Sieht sehr interessant aus. Ich bin gerade dabei, aber es sieht so aus, als würde es eine Weile dauern. Können Sie vorschlagen, wo Sie zuerst suchen sollen?
prog_sr08
1
warte Statistiken . Setzen Sie sie für 2008 und 2012 zurück, lassen Sie die Last für 5 bis 10 Minuten auf beiden
Geräten
Ich fürchte, ich kann die Statistiken zwischen den beiden Servern jetzt nicht vergleichen, da der neue Server eine Live-Site / -Datenbank hostet. Auf dem alten Server blieb die Datenbank, die nicht mehr ausgelastet ist.
prog_sr08
3

Bei den meisten modernen Multi-Core-Systemen und insbesondere Multi-CPU-Systemen ist die Hardwarearchitektur derart, dass bestimmte Teile des Speichers von bestimmten Kernen / Prozessoren weit entfernt sind und bestimmte Teile des Speichers sich in der Nähe bestimmter Kerne / Prozessoren befinden. Dies wird als nicht einheitliche Speicherarchitektur oder kurz NUMA bezeichnet. Sie möchten, dass Ihre MAXDOP-Einstellung mit der Anzahl der Kerne pro NUMA-Knoten übereinstimmt, um die Häufigkeit zu minimieren, mit der ein bestimmter numa-Knoten den eigenen Speicher für Daten verlässt.

Mit den folgenden Schritten können Sie die Konfiguration Ihres neuen Computers überprüfen und sicherstellen, dass MAXDOP hardwaremäßig auf die beste Einstellung eingestellt ist :

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

Ich habe den @ServerRamInMBParameter hier eingefügt, da ich ihn verwende, um die Max Server Memoryund Min Server MemoryKonfigurationsoptionen auf Werte einzustellen, die für den angegebenen Server geeignet sind.

Max Vernon
quelle
1
Ich habe 64 GB RAM, 32 Prozessorkern, 4 numa Knoten. Ich setze den maximalen Parallelitätsgrad auf 8 und den Kostenschwellenwert auf 4. Mit dieser Einstellung und der Option power auf high power werden die SQL Server-Ausführungszeiten wie folgt festgelegt: CPU-Zeit = 550 ms, verstrichene Zeit = 828 ms.
prog_sr08
Das ist also ein Gewinn? Schön zu sehen, dass das bei Ihnen funktioniert!
Max Vernon
0

In welchem ​​Editions- und Lizenzierungsmodus befinden Sie sich? Sie verwenden wahrscheinlich nicht alle Kerne. Beachten Sie den Hinweis auf dieser Seite - http://msdn.microsoft.com/en-us/library/ms143760.aspx

"Die auf der Enterprise Edition mit Server + Client Access License (CAL) basierende Lizenzierung ist auf maximal 20 Kerne pro SQL Server-Instanz beschränkt."

Jeff Sacksteder
quelle
2
Dies würde nur zutreffen, wenn er zuvor eine CAL hatte und ein Großvater war. Selbst mit nur 20 Kernen sollte die Leistung nicht merklich über das frühere System (das nur 8 hatte) fallen.
Aaron Bertrand
Ich habe die Web Edition (limitiert auf weniger als 4 Sockets oder 16 Kerne). Auf dem alten Server hatte ich sowieso nur 8 Kerne.
prog_sr08
0

Ich hatte das gleiche Problem wie das auf dieser Seite beschriebene: Das Umschalten der Leistungseinstellungen von "Ausgeglichen" auf "Hochleistung" hat einen dramatischen Unterschied bewirkt - mehr als die Verdoppelung der Reaktionszeiten. Jetzt, da wir SSDs verwenden, glaube ich nicht, dass der Energieverbrauch das Problem ist, das es gewesen sein könnte.

tom
quelle
-2

Ich habe dieses Problem auch mindestens zwei Wochen lang ohne überzeugende Lösung durchgearbeitet, anstatt ein Problem mit dem anderen zu verwechseln.

Abschließend die Entschließung wie folgt:

  1. Ich habe die Kompatibilität von 010 auf 011 zurückgesetzt

  2. Setzen Sie auch die Kompatibilität der Master-Datenbank zurück. Standardmäßig behält sql die alte Kompatibilitätseinstellung bei. Das müssen wir manuell ändern.

Alles Gute

Pramod Kumar PC
quelle