it-swarm.com.de

SQL Server 2012 langsamer als 2008

Ich habe eine große Website und Datenbank von einem älteren Server migriert (Windows 2008/SQL Server 2008/16 GB RAM/2 x 2,5 GHz Quad Core/SAS)) ) 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 auf dem alten Server getrennt, kopiert und auf dem neuen Server angehängt. Alles lief sehr gut.

Danach habe ich die Kompatibilitätsstufe auf 110 geändert, Statistiken aktualisiert und Indizes neu erstellt.

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.

In einer Tabelle mit etwa 700.000 Datensätzen dauerte eine Indexabfrage auf dem alten Server beispielsweise etwa 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/zu verifizieren ist. Da es mir sehr schwer fällt zu glauben, 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 diesen 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.

EXECUTION PLANS hier hochgeladen: http://we.tl/ARbPuvf9t8

Späteres Update:

  • AMD 2.1 GHz Opteron 16-Core-Prozessoren sehen viel schlechter aus als Intel 2.5 GHz Quad-Core-Prozessoren
  • Große Verbesserung bei der Änderung der Windows-Leistungsoptionen von ausgeglichen auf hohe Leistung
  • Weitere Verbesserung durch Änderung des maximalen Parallelitätsgrads auf 8 und der 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 weitere Vorschläge haben (außer Optimierungen für lokale Abfragen), können Sie diese gerne kommentieren.

16
prog_sr08

Ich hatte ähnliche Probleme mit SQL Server. Möglicherweise ist Ihr Server nicht optimal konfiguriert. Neuere Xeons werden mit TurboBoost, HT usw. geliefert, 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. Sie haben möglicherweise unterschiedliche Namen.

Wir haben auch die Leistung verbessert, indem wir das Windows-Energieverwaltungsprofil von Balanced auf hohe Leistung eingestellt haben. Ein letzter Punkt ist, dass empfohlen wird, bis zu 8 GB Speicher für das Betriebssystem auf x64-Servern zu reservieren. Die Standard-SQL-Installation beansprucht den gesamten Speicher. Möglicherweise möchten Sie eine Reservierung von 4/8GB versuchen, indem Sie Ihre maximale SQL Server-Speicherkonfiguration auf 4/8GB weniger als den Gesamtspeicher einstellen.

Meine Empfehlung wäre, wenn möglich auf den alten Server zurückzugreifen. Wenn Sie keine Regressions-/Automatisierungs-/Ladeskripte zur Verfügung haben, können Sie Ihre Systemaktivität während eines Zeitraums mit hoher Aktivität 1-4 Stunden lang aufzeichnen. Richten Sie dann einen Webserver wie in der Produktion und einen Clientcomputer ein, um das Skript auszuführen. Führen Sie dieselbe Aktivität auf dem neuen Server aus, ändern Sie die Konfiguration 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.

8
AceCTO

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

Sie haben ein Leistungsproblem. Befolgen Sie eine Methode zur Fehlerbehebung bei der Leistung wie Wartezeiten und Warteschlangen , um den Engpass zu identifizieren. 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. Da es zu offen ist und niemand raten kann. Wenn Sie es auf ein bestimmtes Problem eingrenzen, werden Rätselraten vermieden.

Nach dem Update

Die Pläne sind ganz anders. Der alte Plan hatte ein Stream-Aggregat auf dem Stapel, das tatsächlich eine schlechte Kardinalitätsschätzung aufweist (141.000 gegenüber 108.000), und die Hash-Mathematik hat weitere Fehlvorhersagen, umgekehrt (35.000 gegenüber 108.000). Der neue Plan enthält kein Stream-Aggregat und 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 etwas 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). Würde wieder auf eine bessere Ausführung 2012 hinweisen (die Indexwiederherstellung hat möglicherweise die Fragmentierung verringert?).

Was sehr unterschiedlich ist, ist die Anzahl der Threads: 32 in neuen (jeder erhält ~ 23.000 Zeilen) vs. 8 in alten (jeder erhält ~ 95.000 Zeilen). Der Tisch ist ziemlich eng. Es könnte sein, dass die große Anzahl von Threads die Leistung aufgrund der viel häufigeren Cache-Ungültigmachungen tatsächlich beeinträchtigt. Ich würde versuchen:

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

Bemerkte Ihren Kommentar:

Der mit maxdop 8 Query hinzugefügte Ausführungsplan ist auf diese Weise tatsächlich schneller

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

8
Remus Rusanu

Bei den meisten modernen Multi-Core-Systemen und insbesondere bei Multi-CPU-Systemen ist die Hardwarearchitektur so, dass bestimmte Teile des Speichers weit von bestimmten Kernen/Prozessoren entfernt sind und bestimmte Teile des Speichers in der Nähe bestimmter Kerne/Prozessoren liegen. Dies wird als uneinheitliche 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 seinen eigenen Speicher für Daten verlassen muss.

Sie können Folgendes verwenden, um die Konfiguration Ihres neuen Computers zu überprüfen und sicherzustellen, dass MAXDOP auf die beste Einstellung eingestellt ist: hardwarebezogen:

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 das @ServerRamInMB Parameter hier, da ich ihn zum Einrichten des Max Server Memory und Min Server Memory Konfigurationsoptionen für Werte, die für den angegebenen Server geeignet sind.

3
Max Vernon

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

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

0
Jeff Sacksteder

Ich hatte das gleiche Problem wie auf dieser Seite beschrieben: Das Umschalten der Leistungseinstellungen von "ausgeglichen" auf "hohe Leistung" machte einen dramatischen Unterschied - mehr als die Verdoppelung der Reaktionszeiten. Jetzt, wo wir SSDs verwenden, denke ich nicht, dass der Energieverbrauch das Problem ist, das es gewesen sein könnte.

0
tom