Erhöhter RAM, schlechtere Leistung


9

Konfiguration:

  • Windows Server 2008 R2
  • SQL Server 2008 R2 SP1
  • 240 GB RAM
  • TempDB besteht aus 8 x 16 GB großen Datendateien ohne automatisches Wachstum (insgesamt 128 GB).
  • Physischer / eigenständiger Server

Dieser Server wird für die ETL-Verarbeitung verwendet. Wir haben gerade mehr RAM auf diesem Server für insgesamt 240 GB RAM installiert. SQL Server-Dienste sind die einzigen realen Dinge, die ausgeführt werden.

Der Speicher wird im BIOS, OpenManage und Windows einwandfrei angezeigt.

Wenn ich SQL Server so konfiguriere, dass ein Min / Max-Speicher von 70/100 GB verwendet wird, treten keine Probleme auf. Wenn ich diesen Wert jedoch auf 120/150 GB erhöhe, wird beim Ausführen eines unserer ETL-Prozesse der folgende Fehler angezeigt:

Speicherplatz für Objekt '<temporäres Systemobjekt: 422234507706368>' in der Datenbank 'tempdb' konnte nicht zugewiesen werden, da die Dateigruppe 'PRIMARY' voll ist. Erstellen Sie Speicherplatz, indem Sie nicht benötigte Dateien löschen, Objekte in der Dateigruppe löschen, der Dateigruppe zusätzliche Dateien hinzufügen oder das automatische Wachstum für vorhandene Dateien in der Dateigruppe aktivieren. (Nachricht 1105, Status 2, Verfahren unbekannt, Zeile 1)

Dieses Problem ist uns vor dem Ändern der Speicherkonfiguration noch nie begegnet. Nach der Neukonfiguration auf die ursprünglichen 70/100 GB wird dieser Fehler nicht angezeigt.

Dinge, die ich versucht habe:

  1. Stellen Sie die TempDB-Datendateien so ein, dass sie automatisch wachsen. Dies führt einfach dazu, dass die Dateien automatisch wachsen, bis die Festplattenkapazität erreicht ist, und dann fehlschlagen.
  2. Fügen Sie weitere TempDB-Datendateien hinzu. Gleicher Fehler wie gezeigt.
  3. Erhöhen Sie die TempDB-Größe auf 8 x 32 GB (insgesamt 256 GB).

Ich weiß nicht, was dieses Problem verursachen könnte.


2
Ist Ihr Speicher über NUMA-Knoten verteilt? Wie wäre es mit Ihren Prozessoren? Zeigt das SQL Server-Protokoll an, wie viele CPUs beim Start verwendet werden?
Aaron Bertrand

1
Was verwenden Sie für die ETL-Prozesse? SSIS oder ein ähnliches Tool? Wenn es sich um ein Tool außerhalb von SQL Server handelt, führen Sie es auf demselben Server wie Ihre SQL Server-Instanz aus?
Mike Fal

1
Das ist ein guter Punkt @Mike, wenn der ETL-Prozess nicht genügend Speicher abrufen kann, um seine Aufgabe zu erledigen, weil SQL Server zu viel verwendet, muss er möglicherweise die Arbeit auf Tempdb übertragen.
Aaron Bertrand

1
Hier ist ein guter Einstieg in die Überwachung der Tempdb-Nutzung: msdn.microsoft.com/en-us/library/ms176029(v=SQL.105).aspx . Dies sollte Ihnen eine Vorstellung davon geben, was passiert.
Thomas Stringer

2
Haben Sie analysiert, was tatsächlich läuft, wenn Ihre TempDB tatsächlich erweitert wird? Ein einfaches sp_who2 / sp_whoisactive? Es klingt für mich so, als hätten Sie einige lang laufende Transaktionen, die besser verwaltet werden könnten, aber schwer zu sagen sind. Persönlich würde ich mich nicht an die Speicheränderung binden, sondern zuerst den Code überprüfen und prüfen, ob dieser ordnungsgemäß ausgeführt wird.
Mike Fal

Antworten:


3

Vielen Dank an alle für Ihre Hilfe.

Nach dem Durchlaufen einiger Ausführungspläne stellt sich heraus, dass ein JOIN vorhanden ist, der je nach verfügbarem RAM unterschiedlich verarbeitet wird. Mit weniger RAM wird es mit einem Hash ausgewertet. Mit mehr RAM wird eine Reihe von Merge Joins verwendet.

Im Grunde kam es also auf schlecht geschriebenes T-SQL an, das ich derzeit überarbeite.


4
Das ist ziemlich kontraintuitiv, da für einen Hash-Join eine Speicherzuweisung erforderlich ist, für die Zusammenführung jedoch nicht. Gibt es eine zusätzliche Sortieroperation, um den Zusammenführungsbeitrag zu unterstützen?
Martin Smith

1

Dies ist keine Antwort auf die Frage, nur ein Code, den ich nicht in einem Kommentar veröffentlichen wollte. So zeigen Sie das Gleichgewicht zwischen Schedulern und Speicher auf NUMA-Knoten an (und auch, ob Knoten online nicht sichtbar sind):

SELECT 
  parent_node_id, 
  [status],
  AVG(current_tasks_count) AS avg_tasks_count, 
  AVG(load_factor) AS avg_load_factor,
  scheduler_count = COUNT(*)
FROM sys.dm_os_schedulers
GROUP BY parent_node_id, [status];

SELECT 
  memory_node_id, 
  name, 
  SUM(single_pages_kb + multi_pages_kb) AS memory_kb
FROM sys.dm_os_memory_clerks
GROUP BY memory_node_id, name;

(In SQL Server 2012 sollte der letzte SUMsein, SUM(pages_kb)da keine getrennten ein- und mehrseitigen Zuweiser mehr vorhanden sind.)

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.