NUMA, MAXDOP und Co.: Die größten Fehler und Mythen bei der SQL-Server-Konfiguration

von | Nov. 4, 2025 | Fachartikel, SQL Server | 0 Kommentare

Consulting, Beratung

NUMA, MAXDOP und Co.: Die größten Fehler und Mythen bei der SQL-Server-Konfiguration

Einleitung

In der Datenbankadministration von Microsoft SQL Server gibt es eine Reihe von Konfigurationsthemen – insbesondere rund um NUMA (Non-Uniform Memory Access), MAXDOP (Max Degree of Parallelism) und verwandte Einstellungen – bei denen immer wieder typische Fehler, Irrtümer und Mythen auftreten. Falsche Annahmen in diesen Bereichen können die Performance, Skalierbarkeit und Stabilität eines SQL Servers erheblich beeinträchtigen. Dieser Fachartikel richtet sich an Datenbankadministratoren (DBAs) und beleuchtet die größten Missverständnisse und Fehleinstellungen. Dabei geben wir praxisnahe Empfehlungen zur richtigen Konfiguration, um typische Fallen zu vermeiden.

Zunächst werden die häufigsten Irrtümer und Mythen zu NUMA, MAXDOP, Cost Threshold for Parallelism, Hyper-Threading, CPU-Auslastung in virtuellen Umgebungen sowie automatische vs. manuelle Einstellungen erläutert. Anschließend folgt eine ausführliche FAQ-Sektion mit 25 Fragen und Antworten, die häufige Unklarheiten gezielt klärt.  Ziel ist es, DBAs fundierte Hinweise zu geben, wie sie SQL Server-Instanzen optimal konfigurieren und typische Stolpersteine umgehen können.

Falsche Annahmen über NUMA und Auswirkungen auf SQL Server

NUMA-Architektur verstehen: Moderne Server mit mehreren CPU-Sockeln sind oft nach dem NUMA-Prinzip aufgebaut. Das bedeutet, jeder physische Prozessor verfügt über einen lokalen Speicherbereich (RAM), auf den die zugehörigen Kerne schneller zugreifen können als auf Speicher, der an einem anderen Prozessor hängt. Ein NUMA-Knoten umfasst also einen Prozessor (bzw. eine Sockel-Einheit) und den ihm lokal zugeordneten Memory. SQL Server ist von Grund auf NUMA-bewusst – das heißt, die Datenbank-Engine erkennt die NUMA-Topologie des Servers automatisch und verwaltet Arbeitsthreads und Speicher entsprechend.

Irrtum: „NUMA muss man im SQL Server manuell konfigurieren.“ Viele Administratoren glauben, sie müssten spezielle Einstellungen vornehmen, damit SQL Server NUMA unterstützt. Tatsächlich erkennt SQL Server die Hardware-NUMA-Konfiguration von selbst. In der Standardkonfiguration startet SQL Server pro NUMA-Knoten einen Satz Scheduler-Threads und verteilt Last und Speicher allokationen möglichst lokal. Ein manuelles Eingreifen ist in der Regel nicht erforderlich. Nur in Spezialfällen – etwa bei sehr großen Systemen ohne Hardware-NUMA oder bestimmten Optimierungsszenarien – kommt sogenanntes Soft-NUMA ins Spiel. Soft-NUMA unterteilt einen physikalischen NUMA-Knoten bei Bedarf weiter in kleinere Knoten (z.B. um bei >8 Kernen pro Sockel interne Engpässe zu entschärfen). Seit SQL Server 2016 wird Automatic Soft-NUMA sogar automatisch aktiviert, wenn mehr als 8 Kerne pro NUMA-Knoten vorhanden sind. Im Normalbetrieb sollte man diese automatische NUMA-Unterteilung akzeptieren. Eine manuelle NUMA-Konfiguration (etwa per ALTER SERVER CONFIGURATION SET SOFTNUMA oder gar CPU-Affinitätsmasken) ist kaum je nötig – im Gegenteil, solche manuellen Eingriffe können die vom SQL Server intern optimierten Zuteilungen stören und somit eher schaden als nützen.

Irrtum: „Cross-NUMA-Speicherzugriff macht Abfragen extrem langsam.“ Es stimmt, dass ein Thread, der auf Daten im fremden NUMA-Speicher zugreift, einen gewissen Leistungseinbruch erleidet – aber dieser ist in der Regel relativ gering (einige wenige Prozent Mehrlatenz, nicht Größenordnungen). Ein verbreiteter Mythos ist, dass eine Abfrage plötzlich hundertfach langsamer läuft, nur weil Threads über NUMA-Grenzen hinweg auf Speicher zugreifen. Solche dramatischen Performanceeinbrüche deuten meist auf ganz andere Ursachen hin (ineffiziente Abfragen, fehlende Indizes, blockierende Wartezeiten usw.) und nicht primär auf NUMA. Remote Memory Access innerhalb moderner NUMA-Architekturen ist zwar spürbar langsamer als lokal, aber keineswegs so gravierend, dass alleine dadurch Abfragen sekundenlang statt Millisekunden dauern. SQL Server versucht ohnehin, Parallel-Query-Threads auf einen NUMA-Knoten zu konzentrieren, um lokalen Speicherzugriff zu maximieren. Wenn eine Abfrage über mehrere Knoten verteilt wird, kann ein leichter Mehraufwand entstehen – dieser bewegt sich aber typischerweise im Bereich einiger Prozent und nicht im Bereich x-facher Verlangsamung. Die Kernaussage: NUMA-übergreifender Zugriff ist etwas, das man minimieren sollte, aber es ist kein primärer Schuldiger für drastische Performanceprobleme, sofern die Abfragen an sich gut optimiert sind.

Empfehlungen zu NUMA: Überprüfen Sie zuerst, ob Ihr Server tatsächlich aus mehreren NUMA-Knoten besteht (mit SELECT * FROM sys.dm_os_nodes sieht man z.B., wie viele Knoten und ggf. foreign_committed_KB – fremd allokierter Speicher – vorhanden sind). In physischen Umgebungen entspricht die Anzahl NUMA-Knoten meist der Anzahl CPU-Sockel. In virtuellen Umgebungen hängt es davon ab, wie vCPUs auf Sockel aufgeteilt wurden (Stichwort vNUMA – dazu später mehr). Als DBA sollten Sie darauf achten, dass lange laufende, parallelisierte Abfragen nach Möglichkeit innerhalb eines NUMA-Knotens bleiben, um optimalen lokalen Zugriff zu gewährleisten. Dies erreicht man insbesondere durch eine geeignete MAXDOP-Einstellung (siehe nächster Abschnitt). Ferner gilt: lassen Sie SQL Server seine NUMA-Verwaltung selbst durchführen. Stellen Sie sicher, dass im BIOS/UEFI des Servers keine Einstellungen aktiv sind, die NUMA deaktivieren oder alle Speicherbänke zu einer Einheit zusammenfassen (Stichwort „Node Interleaving“ – das sollte aus sein, damit echte NUMA-Performance greift). Greifen Sie nur in absoluten Ausnahmefällen zu manuellen Affinitätsmasken oder Soft-NUMA-Konfigurationen – Standard ist hier am besten. Wenn Sie den Verdacht haben, dass ein NUMA-Ungleichgewicht vorliegt (z.B. ein Knoten viel stärker ausgelastet als ein anderer), prüfen Sie zuerst die Workload-Verteilung und eventuell die Verbindungszuordnung (SQL Server ordnet eingehende Sessions oft rundenbasiert NUMA-Knoten zu). In der Regel lassen sich solche Imbalancen durch gleichmäßigere Workload-Verteilung oder – falls nötig – durch Read-Only-Routing oder andere Architekturentscheidungen entschärfen, nicht jedoch durch Basteln an NUMA-Einstellungen.

Häufige Fehleinstellungen bei MAXDOP und ihre Konsequenzen

Was ist MAXDOP? Die Einstellung Max Degree of Parallelism (MAXDOP) legt fest, wie viele Prozessor-Kerne maximal für die Ausführung einer einzelnen Abfrage (bzw. eines einzelnen parallelisierten Plans) genutzt werden dürfen. Standardmäßig steht MAXDOP auf 0, was bedeutet: keine Obergrenze – SQL Server kann alle verfügbaren logischen Prozessoren einsetzen, wenn der Abfrageoptimierer entscheidet, dass ein paralleler Plan günstig ist. Wichtig: MAXDOP ist keine absolute Angabe, wie viele Threads immer benutzt werden, sondern eine Höchstgrenze. Der Optimierer kann je nach Abfrage auch weniger Threads einsetzen, selbst wenn mehr verfügbar wären. Dennoch hat der MAXDOP-Wert großen Einfluss darauf, wie sich die Last auf dem Server verteilt und wie effizient oder ineffizient Abfragen laufen.

Fehler: MAXDOP auf dem Standardwert 0 belassen bei modernen Systemen. Auf aktuellen Servern mit vielen CPU-Kernen (z.B. 16, 32 oder gar 64 logische Prozessoren) kann ein MAXDOP von 0 dazu führen, dass einzelne komplexe Abfragen viel zu viele parallele Threads erzeugen. Der Optimierungsalgorithmus von SQL Server berücksichtigt zwar den geschätzten Aufwand (Kosten) einer Abfrage, aber der Standard-Threshold (siehe nächster Abschnitt) ist so niedrig, dass viele Abfragen parallelisiert werden. Wenn MAXDOP nicht begrenzt ist, könnten theoretisch sehr große Pläne sämtliche CPU-Kerne einbeziehen. Dies führt in der Praxis häufig zu Über-Parallelisierung: Die Abfrage spawnt beispielsweise 32 Threads, die dann aber mehr Synchronisations-Overhead (Zusammenführen von Teilergebnissen, Verwaltung der Threads etc.) verursachen, als die Parallelisierung an Leistung bringt. Im schlimmsten Fall verschlechtert sich die Performance einer einzelnen Abfrage trotz mehr Kerneinsatz. Außerdem können viele parallele Abfragen gleichzeitig das System an die Grenze bringen: Beispielweise 10 gleichzeitige Abfragen mit je 16 Threads bedeuten 160 laufende Worker-Threads – dies belastet Scheduler und Kontextwechsel und kann sogar die maximal verfügbaren Worker-Threads aufbrauchen (Stichwort THREADPOOL-Waits, wenn dem Server die Worker ausgehen). Empfehlung: Bei Servern mit hoher Kernzahl sollte MAXDOP nicht auf 0 stehen, sondern auf einen sinnvollen Wert begrenzt werden (dazu gleich mehr).

Fehler: MAXDOP immer auf Anzahl gesamter Kerne setzen. Manche Administratoren richten MAXDOP stur nach der Gesamtzahl logischer Prozessoren im System ein – nach dem Motto: „Mein Server hat 16 Kerne, also MAXDOP 16“. Dies kann jedoch bei Multiprozessor-Systemen (mehrere NUMA-Knoten) zu suboptimalen Ergebnissen führen. Der Grund: Setzt man MAXDOP gleich der Gesamtkerne, erlaubt man einer Abfrage, Threads über alle NUMA-Knoten zu verteilen. Besser ist es meist, wenn eine einzelne Abfrage innerhalb eines NUMA-Knotens bleibt, um lokalen Speicher zu nutzen. Hat Ihr Server beispielsweise 2 Sockel mit je 10 Kernen (gesamt 20 logische Prozessoren pro Sockel, falls Hyper-Threading an ist wären es z.B. 40 logisch gesamt), dann sollte MAXDOP so gewählt werden, dass eine Abfrage idealerweise auf höchstens 10 Threads läuft – so bleibt sie innerhalb eines Sockels. Microsofts offizielle Empfehlung lautet sinngemäß: MAXDOP höchstens so hoch wie die Anzahl logischer Prozessoren pro NUMA-Knoten. Bei sehr vielen Kernen pro Sockel wird sogar geraten, nicht alle zu nutzen, sondern etwa halb so viele, maximal jedoch 16. Beispiel: Auf einem System mit 32 logischen CPUs pro NUMA würde man MAXDOP = 16 setzen (halbiert, weil >16). Diese Richtwerte sollen genau verhindern, dass eine Query NUMA-Grenzen überschreitet und mit 32+ Threads mehr Schaden als Nutzen bringt. Praxis-Tipp: Zählen Sie die logischen CPUs pro NUMA-Knoten (z.B. im Task-Manager oder mit SELECT * FROM sys.dm_os_schedulers gruppiert nach parent_node_id). Wählen Sie einen MAXDOP-Wert in der Größenordnung dieser Kernzahl, aber nicht darüber. In vielen Fällen hat sich MAXDOP 8 als guter genereller Richtwert bewährt – insbesondere weil jenseits von 8 Threads die Effizienzgewinne einer einzelnen Abfrage stark abnehmen (der Overhead steigt).

Fehler: MAXDOP vorschnell auf 1 setzen (Parallelismus komplett ausschalten). Aus Angst vor parallelen Abfragen oder auf Empfehlung bestimmter Applikationshersteller (ein bekanntes Beispiel ist SharePoint, das für seine Datenbanken MAXDOP 1 fordert) setzen manche DBAs den Max Degree of Parallelism global auf 1. Dies bedeutet, keine Abfrage kann parallel ausgeführt werden – jede muss strikt seriell auf einem CPU-Kern laufen. Zwar vermeidet man so Probleme durch zu viele parallele Threads komplett, aber man vergibt auch beträchtliches Leistungspotenzial moderner Mehrkernsysteme. Eine komplexe analytische Abfrage oder ein großer Report könnte auf einem 16-Core-Server vielleicht in 5 Sekunden fertig sein, wenn er 8 Kerne nutzen darf – mit MAXDOP 1 dauert er womöglich 40 Sekunden oder länger. Parallelismus ist grundsätzlich etwas Gutes, solange er kontrolliert und gezielt eingesetzt wird. MAXDOP = 1 ist deshalb nur in speziellen Szenarien ratsam: Zum Beispiel wenn eine bestimmte Anwendung nicht parallelisierbare, aber massenhaft gleichzeitig ablaufende Mini-Abfragen absetzt (dann möchte man lieber mehr Einzelabfragen parallel laufen lassen als wenige Abfragen mit je vielen Threads). Oder eben, wenn eine Herstellervorgabe es erfordert (SharePoint nutzt parallelisierte SQL-Abfragen ineffizient, daher die Empfehlung). Für allgemeine OLTP-Datenbanken gilt aber: Ganz ohne Parallelität verschenkt man Performance und entlastet möglicherweise die CPU nicht so gut, wie man denkt. Meist lassen sich selbst bei OLTP-Workloads einige parallele Threads pro Abfrage positiv nutzen, ohne das Gesamtsystem zu stören – etwa indem man MAXDOP auf 2, 4 oder 8 setzt statt auf 1.

Konsequenzen falscher MAXDOP-Einstellungen: Ist MAXDOP zu hoch, kann es – wie oben beschrieben – zu Ressourcenverschwendung und Instabilität kommen. Typische Symptome: Hohe CXPACKET- und CXCONSUMER-Waitzeiten (zeigen Synchronisationswartezeiten zwischen parallelen Threads an), evtl. gefolgt von SOS_SCHEDULER_YIELD (CPU-Engpässe, Threads müssen abgeben) und THREADPOOL-Waits (Thread-Erschöpfung, wenn extrem viele Worker gebraucht werden). Das System wirkt dann trotz vieler Kerne ausgelastet, reagiert träge oder weist einen hohen Kontextwechsel-Overhead auf. Ist MAXDOP zu niedrig, bleiben CPU-Ressourcen ungenutzt – insbesondere bei rechenintensiven Abfragen. Dann sieht man eventuell, dass komplexe Abfragen nur einen Kern voll auslasten und insgesamt länger laufen, während andere Kerne untätig sind. In solchen Fällen dominiert oft SOS_SCHEDULER_YIELD die Wait-Statistiken, weil einzelne Threads um CPU-Zeit kämpfen, obwohl insgesamt noch Luft wäre. Die Kunst ist es, hier einen Mittelweg zu finden.

Empfehlungen zu MAXDOP: Orientieren Sie sich an bewährten Richtwerten, passen Sie diese aber an Ihre Umgebung an. Eine häufig empfohlene Faustregel:

  • Bis 8 logische Prozessoren pro NUMA-Knoten: MAXDOP gleich Anzahl logischer CPUs (also z.B. 4 Kerne => MAXDOP 4, 8 Kerne => MAXDOP 8).
  • Mehr als 8 logische Prozessoren pro Knoten: MAXDOP auf 8 begrenzen (oft ausreichend für die meisten Abfragen).
  • Bei sehr großen Knoten (>16 logische CPUs): ggf. noch niedriger als die Kernzahl, z.B. Hälfte der Kerne, aber nicht über 16.

Wichtig ist auch der Workload-Typ: Bei reinen OLTP-Systemen mit vielen kleinen Transaktionen und kaum Analysen fährt man mit einem relativ niedrigen MAXDOP (z.B. 4 oder sogar 2) oft am besten, damit nicht tausende Mini-Abfragen plötzlich parallelisieren. In Data-Warehouse- oder BI-Systemen mit großen Abfragen darf MAXDOP ruhig höher sein (8 oder auch 16), um den massiv parallelen Verarbeitungsbedarf zu decken. Testen Sie Änderungen gründlich – beobachten Sie, wie sich ein geänderter MAXDOP-Wert auf typische Lastspitzen auswirkt. Moderne SQL Server (ab 2019) schlagen bei der Installation übrigens automatisch einen MAXDOP-Wert vor, basierend auf den erkannten Kernen und NUMA-Knoten. Dieser empfohlene Wert ist meist konservativ (Microsoft neigt dazu, eher etwas niedrigere MAXDOPs vorzuschlagen, um im Zweifel Über-Parallelisierung zu vermeiden). Es schadet nicht, diesen Vorschlagswert als Ausgangsbasis zu nehmen. Dennoch: Verlassen Sie sich nicht blind auf Defaults – überprüfen Sie mit Wait-Statistiken und Ausführungsplänen, ob Ihre Abfragen effizient laufen. Wenn Sie häufig CXPACKET-Waits sehen und CPU-Kerne ungenutzt bleiben, könnte MAXDOP zu hoch sein (bzw. Cost Threshold zu niedrig, siehe unten). Wenn komplexe Abfragen hingegen alle nur einen Thread nutzen und lange dauern, könnte MAXDOP zu strikt oder der Cost Threshold zu hoch sein.

Irrtümer rund um den Cost Threshold for Parallelism

Was bewirkt der Cost Threshold for Parallelism? Diese oft übersehene Server-Option definiert den Kosten-Schwellenwert, ab dem der Abfrageoptimierer überhaupt anfängt, einen parallelen Ausführungsplan in Erwägung zu ziehen. Der „Cost“ bezieht sich auf die geschätzten Ausführungskosten eines Plans, gemessen in SQL Servers internen Einheiten (eine abstrakte Maßeinheit, die CPU- und IO-Kosten kombiniert – nicht direkt Sekunden oder ähnliches, aber als grober Richtwert). Standardmäßig steht der Cost Threshold auf 5. Das bedeutet: Wenn eine Abfrage einen geschätzten Kostenwert über 5 hat, darf sie parallel ausgeführt werden (vorbehaltlich anderer Bedingungen). 5 war vor vielen Jahren (in den 1990ern) ein vernünftiger Wert – damals bedeuteten Kosten >5 bereits relativ „teure“ Abfragen, bei denen Parallelisierung lohnenswert sein könnte. Heute ist dieser Standardwert meist zu niedrig. Moderne Server und Datenbanken können viele Abfragen mit Kosten jenseits von 5 spielend seriell bewältigen. Inzwischen entspricht ein Kostenwert von 5 oft einer recht leichten Abfrage, die auch auf einem Kern schnell laufen würde. Das Resultat: Mit dem Default-Wert 5 werden auf aktuellen Systemen viel zu viele Abfragen parallelisiert, auch solche, die kaum etwas tun. Jeder parallele Plan bringt aber einen gewissen Overhead mit sich – so kann es passieren, dass simple Abfragen durch Parallelisierung sogar verlangsamt werden statt beschleunigt (der Aufwand für Thread-Management, Synchronisation etc. frisst den Nutzen auf).

Irrtum: „Den Cost Threshold muss man nicht anrühren.“ Viele lassen diese Einstellung auf dem Default, weil sie weniger bekannt ist als MAXDOP. Dabei gehen MAXDOP und Cost Threshold Hand in Hand: MAXDOP bestimmt wie stark parallel, der Cost Threshold bestimmt ob überhaupt parallel. Wer nur MAXDOP optimiert, aber den Threshold bei 5 belässt, wird ggf. immer noch sehr viele parallele Klein-Abfragen haben – nur eben jede mit weniger Threads. Empfehlung: Für die meisten Umgebungen lohnt es sich, den Cost Threshold for Parallelism deutlich anzuheben. Ein oft genannter Richtwert für OLTP-Systeme ist 50. Das heißt, Abfragen mit geschätzten Kosten unter 50 werden seriell abgearbeitet; erst darüber setzt der Optimierer parallele Pläne an. Dieser Wert 50 ist kein Dogma – er beruht auf Beobachtung, dass heutzutage Kosten <50 häufig für relativ kurze Abfragen anfallen, die man nicht parallel ausführen muss. Manche DBAs wählen auch 20 oder 30 als Kompromiss, andere gehen auf 100 hoch, je nach Workload. Wichtig ist: Weg von 5! Der Standardwert ist veraltet und in typischen Fällen suboptimal.

Irrtum: „Der Cost-Wert entspricht Sekunden oder Prozent.“ Ein Missverständnis bei weniger erfahrenen Kollegen ist, dass der „Kosten“-Wert eine reale Zeitangabe sei, z.B. „5“ stünde für 5 Sekunden Laufzeit. Das ist falsch – die Kostenberechnung in SQL Server ist komplex und resultiert in abstrakten Zahlen, die nur relativ zueinander aussagekräftig sind. Eine Abfrage mit Kosten 10 könnte in Wirklichkeit in 50 ms laufen, während eine andere mit Kosten 2 vielleicht 500 ms dauert – je nach Plan und Statistik. Der Cost Threshold legt lediglich fest, ab welchem Punkt in der Optimierer-Schätzung Parallelität in Betracht gezogen wird. Deshalb muss man den absoluten Zahlenwert experimentell ermitteln, was sinnvoll ist. Viele haben mit ~50 gute Erfahrungen gemacht, weil damit trivialere Abfragen (Selects kleinerer Tabellen, punktuelle Index-Suchen etc.) seriell bleiben.

Folgen einer falschen Cost-Threshold-Einstellung: Ist der Schwellenwert zu niedrig (Standard 5 oder ähnlich), werden zu viele „leichte“ Abfragen parallel ausgeführt. Symptome: Im Abfrage-Store oder beim Plan-Cache sieht man sehr viele Pläne mit parallelen Ausführungen, obwohl die Abfragen klein sind. CXPACKET/CXCONSUMER-Waits treten gehäuft auf, obwohl eigentlich keine heavy queries laufen. Möglicherweise tauchen auch SOS_SCHEDULER_YIELD-Waits auf, weil die CPU-Zeit durch viele unnötige Threads aufgesplittert wird. Insgesamt wirkt das System überbremst, obwohl genug Leistung da wäre – schlicht, weil die Parallelisierung zu aggressiv greift. Ist der Schwellenwert zu hoch (z.B. man würde ihn extrem hoch setzen wie 1000), dann bleiben selbst sehr aufwendige Abfragen seriell. Dann sieht man, dass CPU-intensivere Abfragen nicht parallelisieren, die CPU-Auslastung pro Abfrage dadurch unnötig lange auf einem Kern klebt und Gesamt-CPU möglicherweise sogar höher ist. Indikator: Überwiegend SOS_SCHEDULER_YIELD-Waits (bedeuten, Threads warten auf freie CPU, weil alles single-thread läuft) und Abfragen, die spürbar schneller gingen, wenn sie parallel laufen dürften.

Empfehlungen zum Cost Threshold: Erhöhen Sie diesen Wert schrittweise und beobachten Sie die Auswirkungen. Ein pragmatischer Ansatz: Springen Sie von 5 zunächst auf 20 und lassen den Server einen vollen Lastzyklus (z.B. einen Arbeitstag oder Batch-Zyklus) laufen. Schauen Sie, ob sich die Wait-Statistiken verbessern (möglicherweise sinkt die Anzahl paralleler Threads deutlich). Danach können Sie weiter steigern: z.B. auf 30, dann 50. Die meisten erfahrenen DBAs setzen heute mindestens 30-50 an. Bei datenintensiven OLAP-Systemen kann man den Wert auch noch höher setzen, wenn man sicherstellen will, dass wirklich nur die ganz großen Abfragen parallelisieren. Wichtig: Parallel mit MAXDOP denken. Wenn Sie Cost Threshold erhöhen, bewerten Sie auch, ob Ihr MAXDOP-Wert noch passt – und umgekehrt. Beide Einstellungen zusammen bestimmen das Parallelismus-Verhalten. Ein guter Cost Threshold reduziert unnötige Parallelausführung; ein guter MAXDOP stellt sicher, dass notwendige Parallelität effizient bleibt. Und vergessen Sie nicht die Tests: Prüfen Sie nach Änderungen exemplarisch einige schwere und einige leichte Abfragen. Optimal ist, wenn kleine Abfragen nun seriell laufen (keine „exchange operators“ im Ausführungsplan für simple SELECTs) und große Abfragen weiterhin parallel laufen, aber kontrolliert.

Missverständnisse beim Zusammenspiel von Hyper-Threading, CPUs und logischen Prozessoren

Hyper-Threading erklärt: Unter Hyper-Threading (bei AMD auch „SMT“) versteht man die Technik, dass ein physischer Prozessorkern zwei (oder mehr) logische Prozessoren bereitstellt. Das Betriebssystem sieht also beispielsweise 16 logische CPUs, obwohl physisch nur 8 Kerne vorhanden sind. Jeder Kern kann zwei Threads nahezu gleichzeitig bearbeiten, indem brachliegende Rechenwerke ausgenutzt werden. In der Praxis bringt Hyper-Threading keine Verdopplung der Leistung, aber doch meist einen Zugewinn von etwa 20–30% pro Kern bei voll ausgelasteten Workloads. SQL Server behandelt jeden logischen Prozessor als eigenen Scheduler und plant Threads darauf, als wären es echte Kerne – ist jedoch intern „Hyperthreading-aware“.

Missverständnis: „Mehr logische Prozessoren = entsprechend mehr Leistung.“ Viele gehen davon aus, dass z.B. 16 vCPUs immer doppelt so schnell sind wie 8 vCPUs. Das stimmt bei Hyper-Threading so nicht: 16 logische auf 8 physischen Kernen bringen vielleicht ~130% der Leistung von 8 physischen, aber nicht 200%. Wenn SQL Server also 16 Scheduler (logische CPUs) hat, steckt dahinter eventuell nur die Leistung von 8 echten Kernen plus etwas hyperthreading-Zusatz. Planen Sie Kapazitäten daher nach physischen Kernen, nicht nach logischen. Eine typische Falle: Man gibt einer VM so viele vCPUs wie das Hostsystem logische hat, in der Annahme, man bekäme alle Ressourcen – in Wirklichkeit teilt man sich aber ggf. die physischen Kerne mit dem zweiten Hyper-Thread und mit anderen VMs (siehe nächster Abschnitt). Für die SQL-Server-Konfiguration bedeutet das auch: Bei MAXDOP-Empfehlungen, die von „logischen Prozessoren“ sprechen, sollte man im Hinterkopf behalten, dass über 8 hinausgehende logische CPUs oft nur Hyper-Threads sind. Beispiel: 1 NUMA-Knoten mit 16 logischen (8 Kerne mit HT) – hier empfiehlt Microsoft MAXDOP 8. Warum? Weil ab 9 die zusätzlichen sind nur die zweiten Threads der Kerne, die bringen weniger und belasten den gemeinsamen Kern-Cache etc. Somit ist oft 8 das sinnvolle Limit, auch wenn 16 „CPUs“ da sind.

Irrtum: „Hyper-Threading abschalten löst CPU-Probleme immer.“ Es gibt eine kontroverse Diskussion, ob man in reinen SQL-Server-Maschinen Hyper-Threading deaktivieren sollte, um „vollwertige“ Kerne zu haben. Die meisten Erfahrungen zeigen: Hyper-Threading an bringt in gemischten Workloads einen Vorteil, weil es die Durchsatzleistung erhöht – sprich, mehr Threads können produktiv Arbeit erledigen, auch wenn einzelne Threads nicht schneller werden. Gerade bei vielen parallelen kleineren Abfragen (typisch OLTP) profitiert man vom höheren Durchsatz der virtuellen Kerne. Anders kann es bei sehr CPU-intensiven, einzelthreadigen Workloads sein (z.B. komplexe Berechnungen): Hier könnte das Deaktivieren von Hyper-Threading pro Kern etwas mehr Cache und Ressourcen pro Thread lassen und so minimal Performance pro Thread steigern. Insgesamt gilt aber: Pauschal Hyper-Threading auszuschalten ist selten sinnvoll. Besser ist es, die Thread-Platzierung dem SQL Scheduler und dem OS zu überlassen. SQL Server weiß um die CPU-Topologie: Er verteilt z.B. parallele Abfrage-Threads möglichst so, dass zuerst leere Kern-Paare genutzt werden, bevor er anfängt, die zweiten Hyper-Threads von schon belegten Kernen zu belegen (sofern möglich). So erreicht man, dass wenn nur wenige Threads gebraucht werden, sie auf unterschiedlichen physischen Kernen laufen (maximale Leistung), und erst wenn richtig viel parallel los ist, auch die Hyper-Thread-Kapazität ausgereizt wird.

Missverständnis: „Logische Prozessoren im Task-Manager = dedizierte Kerne für SQL.“ In vielen Virtualisierungs- oder auch Cloud-Umgebungen sieht man z.B. „8 vCPUs“ und nimmt an, das entspräche 8 ganzen Kernen. Tatsächlich könnten das aber 8 logische auf 4 physischen Kernen sein (wenn Hyper-Threading am Host an ist und die VM auf einem Sockel sitzt). Als DBA sollte man die Hardware-Zusammenhänge kennen: Prüfen Sie, ob die bereitgestellten vCPUs Hyper-Threads oder ganze Kerne repräsentieren. Manche Hypervisoren geben standardmäßig nur halbe Kerne als vCPU, um die Verteilung feiner zu machen. Das kann Auswirkungen haben: z.B. beim MAXDOP-Tuning oder generell bei Performance-Erwartungen. Tipp: Bei dedizierten SQL-Servern, vor allem On-Premises, kann man in BIOS/UEFI meist die Option „Hyper-Threading“ toggeln. Wenn Ihr SQL Server konstant an CPU-Grenzen stößt und vor allem ein paar wenige Abfragen die CPU dominieren, kann man testweise HT deaktivieren und schauen, ob die Latenzen besser werden. In den meisten Fällen wird man aber eher versuchen, Query-Tuning oder bessere Parallelisierung einzusetzen, statt Kerne zu deaktivieren.

Hyper-Threading und MAXDOP: Ein oft übersehener Punkt: Wenn Hyper-Threading aktiv ist, bedeutet ein MAXDOP-Wert, dass so viele logische Prozessoren genutzt werden können. Beispiel: MAXDOP 8 auf einem 8-Kern-mit-HT-System heißt, eine Abfrage könnte im Extremfall alle 8 physischen Kerne belegen (weil das 16 logische hat, aber wir deckeln auf 8 logische Threads). So weit, so gut – dann sind entweder 8 Kerne voll genutzt oder 4 Kerne doppelt. Hätte man hier MAXDOP 16 gelassen (bei 16 logischen), könnte ein Query alle 8 Kerne mit jeweils beiden Hyperthreads belegen, was ineffizient sein kann. Daher passt die Empfehlung MAXDOP 8 hier genau: Sie nutzt maximal einen Thread pro physischem Kern. Für DBAs bedeutet das: Wenn Sie den Rat „MAXDOP = 8“ hören, steckt oft die Annahme dahinter, dass Hyper-Threading an ist. Wenn aus irgendwelchen Gründen Hyper-Threading aus ist (also logische = physische Kerne), dann kann man eventuell auch einen etwas höheren MAXDOP in Erwägung ziehen, weil dann wirklich 8 physische Kerne genutzt werden. Doch in den meisten Szenarien belässt man HT an und nimmt 8 als sinnvolles Limit, weil jenseits davon eben nur noch die zweite Thread-Ebene der Kerne aktiviert wird.

Empfehlungen zu Hyper-Threading & CPU-Planung: Lassen Sie Hyper-Threading in der Regel eingeschaltet, denn es verbessert die Gesamt-Throughput-Kapazität des Servers. Achten Sie aber darauf, Hyper-Threads nicht als echte doppelte Kernanzahl zu verplanen. Im Monitoring sollten Sie wissen: Eine CPU-Auslastung von 50% auf einer HT-Maschine heißt unter Umständen, dass alle physischen Kerne voll ausgelastet sind (weil die Auslastung sich auf 16 logische rechnet, was 8 physische zu 100% plus 8 hyperthreads zu 0% bedeuten könnte). Die Interpretation von CPU-Metriken ist also etwas komplexer mit HT. Als grobe Orientierung: Wenn Ihr SQL Server ständig sehr hohe CPU-Auslastung zeigt und kaum Leerlauf hat, und Sie bereits MAXDOP & Co. optimiert haben, dann sind wahrscheinlich auch alle Hyper-Threads aktiv – in dem Fall bringt HT an vs. aus keine Wunder. Umgekehrt, falls Sie hohe SOS_SCHEDULER_YIELD Waits sehen und die CPU-Auslastung trotzdem nicht bei 100% liegt, könnte es sein, dass einige Threads auf zweiten Hyper-Threads laufen und nicht genug bekommen. Feintuning auf Hyper-Threading-Ebene ist aber selten nötig. Vertrauen Sie primär auf die genannten Parallelisierungs-Settings (MAXDOP, Cost Threshold) und auf eine ausreichende Maximale Arbeitsthreadzahl (die lässt man i.d.R. auf „0“, damit SQL automatisch genügend Worker-Threads bereitstellt – manuelle Änderungen an max worker threads sind fast nie erforderlich, SQL kalkuliert intern basierend auf Prozessoren einen sinnvollen Wert). Abschließend: Hyper-Threading ist kein Hexenwerk – es bringt solide Vorteile, solange man die Leistung nicht überschätzt. Deaktivieren sollte man es nur, wenn spezifische Tests in Ihrer Umgebung zeigen, dass dadurch die Leistung spürbar stabiler oder besser wird (was selten der Fall ist).

Typische Konfigurationsfehler in Virtualisierungsumgebungen

In virtualisierten Umgebungen (VMware, Hyper-V, Azure VMs etc.) kommen zu den bisherigen Aspekten noch einige Besonderheiten hinzu. Hier die häufigsten Konfigurationsfehler, die DBAs bei SQL Server-VMs machen – und wie man sie vermeidet:

Fehler 1: CPU Overcommit – zu viele vCPUs im Verhältnis zur Hardware. Ein starker SQL Server benötigt CPU-Ressourcen. Ein verbreiteter Irrtum in Virtualisierungsumgebungen ist, man könne mehr vCPUs vergeben als physische Kerne vorhanden sind, ohne Nachteile („die Hypervisor magisches Scheduling wird’s schon richten“). Das sogenannte Overcommitting führt jedoch schnell zu Performanceproblemen: Wenn mehrere VMs gleichzeitig Rechenzeit fordern, muss der Hypervisor die physischen Kerne zwischen den VMs aufteilen. Das äußert sich in erhöhter CPU Ready Time (die VM wartet auf CPU-Zuteilung) und kann zu sporadischen Latenzen oder durchgehend verminderter Performance führen. Praxisbeispiel: Angenommen, Ihr Host hat 16 physische Kerne (32 logische mit HT). Sie betreiben darauf 4 VM-Instanzen mit je 16 vCPUs. Solange nicht alle VMs gleichzeitig Last machen, mag das okay aussehen. Aber sobald zwei oder mehr VMs voll ausgelastet sind, kämpfen sie um dieselben Kerne – die Hypervisor-Planung wechselt ständig zwischen ihnen, was in jeder VM zu weniger effektiver Rechenleistung und mehr Wartezeit führt. Empfehlung: Überbuchen Sie CPU bei wichtigen SQL-VMs nicht. Im Idealfall geben Sie einer produktiven SQL-VM dedizierte Kerne des Hosts (z.B. per CPU-Reservation oder indem Sie sicherstellen, dass die Summe der vCPUs auf dem Host die physikalischen Kerne nicht übersteigt). Falls ein gewisses Overcommit unvermeidlich ist (z.B. in Cloud-Umgebungen oder wenn mehrere VMs sich Host teilen), dann achten Sie zumindest darauf, dass nicht alle VMs gleichzeitig Volllast haben können. Planen Sie Kapazität so, dass genügend Puffer bleibt.

Fehler 2: Ungünstige vCPU-NUMA-Konfiguration. Virtuelle Maschinen mit vielen vCPUs müssen dem Gastbetriebssystem eine NUMA-Topologie präsentieren, damit dieses (und der SQL Server darin) optimal arbeiten können. Standardmäßig tun Hypervisoren dies mit dem Konzept vNUMA automatisch – aber nur, wenn gewisse Bedingungen erfüllt sind. Ein häufiger Fehler ist es, eine VM mit z.B. 12 vCPUs auf einem Host mit 2×8 physischen Kernen einzurichten und dabei alle vCPUs als ein Sockel zu konfigurieren (Cores per Socket = 12). In diesem Fall denkt das Gast-OS (und damit SQL Server), es gäbe einen NUMA-Knoten mit 12 CPUs. Der Host hingegen wird diese 12 vCPUs auf 2 physische Knoten à 6 Kerne verteilen (weil je 8 pro Sockel vorhanden, passt 12 nicht in einen). Ohne vNUMA-Info weiß der SQL Server davon nichts – er sieht ein „großes CPU“, während tatsächlich zwei kleinere mit geteiltem Memory dahinter stehen. Die Folge: unerwarteter Remote Memory Zugriff und suboptimale Thread-Verteilung. Empfehlung: Bei großen VMs (mehr vCPUs als der Host-Kernanzahl pro Sockel) sollte vNUMA aktiviert sein, damit die VM die physische NUMA-Topologie korrekt spiegelt. In VMware z.B. erreicht man das, indem man die vCPU-Zahl pro virtuellen Sockel begrenzt (z.B. 6 vCPUs pro Sockel, 2 Sockel à 6 Kerne, um 12 vCPUs zu modellieren). So „sieht“ die VM dann 2 NUMA-Knoten und SQL Server kann seine Scheduler entsprechend gruppieren. Die Hypervisoren (VMware, Hyper-V) aktivieren vNUMA meist automatisch, sobald eine VM mehr vCPUs hat als ein Sockel des Hosts Kerne – aber nur, wenn die VM nicht so konfiguriert ist, dass sie alles in einem Sockel packt. Also: Cores-per-Socket richtig einstellen oder im Zweifel auf Standard belassen, damit der Hypervisor sinnvoll splittet.

Fehler 3: Dynamische Ressourcen (Memory Ballooning, Dynamic Memory) für SQL Server nutzen. Einige Virtualisierungslösungen bieten die Möglichkeit, dynamisch RAM zuzuteilen oder per Ballooning Speicher zurückzufordern, wenn er nicht aktiv genutzt wird. Für SQL Server ist das Gift für die Performance. SQL Server verwaltet seinen Speicher (Buffer Pool etc.) sehr selbstbewusst: Wenn man ihm z.B. 64 GB zuweist (Max Server Memory entsprechend konfiguriert), dann geht er davon aus, diese 64 GB gehören ihm langfristig. Wenn der Hypervisor nun im Hintergrund meint, 20 GB davon seien „ungenutzt“ und könnte sie vorübergehend entziehen, gerät SQL Server in Schwierigkeiten – plötzlich fehlen Seiten im RAM, es kann zu unerwartetem Paging kommen, im schlimmsten Fall lagert das Betriebssystem Datenbankseiten aus. Empfehlung: Weisen Sie SQL-Server-VMs statische, feste Ressourcen zu. Deaktivieren Sie „Dynamisches Speichern“ (bei Hyper-V) für produktive SQL-VMs. In VMware sollte man einen großzügigen Speicherreservierungswert setzen (idealerweise 100% des zugeteilten RAMs, was Ballooning für diese VM ausschließt). So stellen Sie sicher, dass der SQL Server wirklich über den zugesagten RAM verfügt und dieser nicht stillschweigend woanders verwendet wird.

Fehler 4: Falsche Speicher- und CPU-Einstellungen innerhalb der VM. Auch innerhalb der VM gelten alle bisherigen Grundsätze: Viele DBAs vergessen aber, bei einer virtuellen SQL Server-Instanz die üblichen Einstellungen vorzunehmen. So wird etwa oft Max Server Memory auf Default belassen (Standard ist „unbegrenzt“, was in einer VM besonders gefährlich sein kann, da das OS der VM selbst nur begrenzt RAM hat und man leicht in Volllast alles belegt und eventuell Windows anfängt zu swapen). Ebenso wird lock pages in memory (LPIM) manchmal nicht gesetzt – wobei LPIM in einer VM auch kein Allheilmittel ist, vor allem wenn der Host überbucht ist. Empfehlung: Behandeln Sie Ihre VM wie einen physischen Server, was SQL-Einstellungen betrifft: Setzen Sie einen sinnvollen oberen Grenzwert für den SQL-Server-Speicher, sodass das Gast-OS ~2-4 GB Puffer behält. Aktivieren Sie lock pages in memory (bei Standard/Enterprise Edition), um zu verhindern, dass Windows den SQL-Buffer auslagert. Passen Sie MAXDOP und Cost Threshold an, wie oben beschrieben – gerade in VMs mit beschränkter CPU lohnt es, ineffiziente Parallelpläne zu vermeiden.

Fehler 5: Veraltete virtuelle Hardware und Power-Settings. Etwas abseits von SQL-Konfiguration, aber dennoch praxisrelevant: Wird eine VM auf einem Host betrieben, auf dem z.B. CPU Stromsparmechanismen (C-States, niedrige Performance-Profile) aktiv sind, kann es zu schwankenden Latenzen kommen. Ebenso, wenn man in der VM nicht die paravirtualisierten Gerätetreiber nutzt (z.B. immer noch alte IDE-Controller oder langsame virtuelle NICs). Empfehlung: Schalten Sie für Host-Server mit kritischen SQL-VMs den Hochleistungsmodus im BIOS und Betriebssystem ein (kein „Balanced Power“, sondern „High Performance“ Energieprofil). Nutzen Sie aktuelle VM-Hardware-Versionen und Treiber: in VMware z.B. den Paravirtual SCSI-Controller für Datenplatten, VMXNET3 für Netzwerk etc., da diese effizienter arbeiten. Diese Maßnahmen reduzieren Latenz und erhöhen die Stabilität unter Last, was insbesondere für E/A-intensive Datenbank-Workloads wichtig ist.

Zusammengefasst: In Virtualisierungsumgebungen muss man besonders auf das gesamte Zusammenspiel achten – Host und VM. Ein SQL Server kann nur so performant sein wie die Ressourcen, die der Hypervisor ihm wirklich zur Verfügung stellt. Typische Fehler wie CPU-Overcommitment und unpassende vNUMA-Konfiguration führen dazu, dass SQL Server seine Stärken nicht ausspielen kann. Durch kluge VM-Größenwahl (lieber etwas weniger vCPUs, dafür keine Überschneidung mit anderen VMs), korrekte vNUMA-Einstellungen und fest zugewiesene Memory-Ressourcen legen Sie die Grundlage, dass Ihr SQL Server in der VM ähnlich verlässlich läuft wie auf Blech.

Mythen zu automatischen vs. manuellen Einstellungen

Automatische Einstellungen sind bequem – man installiert SQL Server, lässt alles auf Default und hofft, die Software „wird schon wissen, was sie tut“. Auf der anderen Seite neigen manche Administratoren dazu, unzählige Parameter manuell zu tweaken, oft nach zweifelhaften „Best Practices“. Schauen wir uns einige Mythen an:

Mythos: „SQL Server ist out-of-the-box optimal konfiguriert.“ Leider trifft das nur auf einfache, kleine Umgebungen zu. Microsoft liefert SQL Server mit Defaults aus, die eine breite Masse an Fällen irgendwie abdecken, aber nicht spezialisiert sind. Einige Standardwerte sind historisch bedingt und längst überholt (etwa der erwähnte Cost Threshold = 5). Andere Defaults gehen von konservativen Annahmen aus – zum Beispiel lässt SQL Server standardmäßig den Speicher unbegrenzt („Maximum server memory = 2 Petabyte“ quasi). Das mag auf einem dedizierten Server okay sein, aber in der Praxis muss ein DBA immer zumindest den Max-Speicher konfigurieren, damit das OS nicht hungert. Weitere Beispiele: Das TempDB-Setup in neueren Versionen ist zwar verbessert (SQL Server legt automatisch mehrere TempDB-Dateien an), aber je nach System ist die Anzahl und Größe evtl. nicht optimal – hier lohnt sich manuelles Nachjustieren. Oder das Thema Autogrowth-Einstellungen für Datenbanken: Standardmäßig in Prozent, was bei großen DBs unsinnig ist (man schaltet besser auf feste MB-Werte). Fazit: Wer alles auf „Automatik“ belässt, riskiert ungenutztes Potenzial und teils vermeidbare Probleme. Ein DBA sollte die wichtigen Stellschrauben kennen und setzen.

Mythos: „Manuelles Tuning jedes Parameters bringt maximale Performance.“ Die Kehrseite: Es gibt Administratoren, die sofort an dutzenden versteckten Schaltern drehen – etwa diverse Trace Flags aktivieren, an den Recovery-Intervallen schrauben, parallel jedes erdenkliche Feature wie Resource Governor profilaktisch aufsetzen usw. Nicht jede Umgebung braucht Feintuning auf allen Ebenen. Viele Einstellungen sind bewusst adaptiv oder „intelligent“ im SQL Server implementiert. Beispiel: Die max worker threads lässt man am besten auf 0 (auto) stehen – SQL Server berechnet dann basierend auf der CPU-Anzahl einen angemessenen Thread-Pool (bei vielen CPUs werden es automatisch mehr Threads). Greift man hier manuell ein, kann man sowohl zu niedrig ansetzen (dann droht früher Thread-Mangel) als auch überhöhen (unnötiger Overhead im Thread-Scheduling). Ähnliches gilt für Parallelität per Abfrage: Man könnte natürlich via Query-Hints oder Resource Governor sehr granular steuern, welcher Workload wie viele Threads bekommt – aber das ist oft nicht nötig, wenn globale Settings stimmen. Ein weiteres Beispiel: Auto-Update und Auto-Create von Statistiken – das sind automatische Einstellungen, die man nur in Ausnahmefällen abschalten sollte. Sie sorgen dafür, dass SQL Server selbsttätig Statistiken anlegt und aktualisiert. Wer hier in blinder Optimierungswut „alles manuell“ machen will, handelt sich u.U. mehr Arbeit und neue Probleme ein (veraltete Statistiken, suboptimale Pläne). Kurzum: Manuelles Feintuning sollte gezielt und datenbasiert erfolgen, nicht pauschal.

Empfehlung: Den Mittelweg finden. Moderne SQL Server-Versionen bieten einige automatische Optimierungsfunktionen, die man nutzen sollte. Zum Beispiel: Intelligent Query Processing (ab SQL 2019) passt intern Dinge wie Memory Grants, Batch Mode usw. dynamisch an, ohne dass der DBA jedes Query-Plan-Detail anfassen muss. Oder Query Store und neuerdings DOP Feedback (Degree of Parallelism Feedback in SQL 2022) – diese Features können automatisch erkennen, wenn eine Abfrage konsistent zu viele oder zu wenige Parallel-Threads nutzt, und zukünftige Ausführungen entsprechend anpassen. Solche Automatiken sind willkommen und sollten aktiviert sein, da sie auf Basis realer Laufzeiten justieren. Im Gegensatz dazu bleiben aber globale Einstellungen wie MAXDOP, Cost Threshold, Memory etc. weiter in der Verantwortung des DBAs. Ein guter Ansatz ist: Minimalkonfiguration manuell vornehmen, dann beobachten und iterativ optimieren. Minimal heißt: Setzen Sie die wesentlichen Parameter auf sinnvolle Werte für Ihre Umgebung – insbesondere – MAXDOP (wie oben erläutert), – Cost Threshold for Parallelism, – Max Server Memory, – gegebenenfalls die Anzahl der TempDB-Dateien (z.B. 1 Datei pro 4 Kerne, bis max. ~8 Dateien als grobe Richtlinie), – und aktivieren Sie Best Practices wie optimize for ad hoc workloads (um Plan Cache Bloat durch Einmalabfragen zu reduzieren) oder backup compression (spart IO bei Backups).

Haben Sie diese Baseline gesetzt, messen Sie kontinuierlich (Performance-Monitoring, Wait Statistics, Index-Nutzung etc.). Greifen Sie nur dann in weitere Settings ein, wenn ein konkretes Problem oder eine klare Datenbasis dafür spricht. Zum Beispiel: Wenn Sie trotz korrekt gesetztem MAXDOP immer noch sehr hohe CXPACKET-Waits haben, prüfen Sie Query Store – eventuell gibt es einzelne Abfragen, die mit einem Hinweis (Query Hint) oder per Resource Governor begrenzt werden sollten, statt global alles zu ändern. Oder wenn der Query Store zeigt, dass DOP Feedback dauernd Abfragen von DOP 8 auf DOP 4 herunterstuft, könnte man überlegen, global MAXDOP 4 zu setzen. Automatik und Manuell schließen sich nicht aus, sie ergänzen sich. Die Kunst ist zu wissen, wann man den Algorithmen des SQL Servers vertraut und wann man selbst eingreifen muss.

Spezialfall automatische Updates: Microsoft veröffentlicht mit Service Packs und Cumulative Updates manchmal auch Verbesserungen an den Standardwerten oder an der Automatik. Zum Beispiel wurde in Azure die Default-MAXDOP inzwischen auf 8 gesetzt, weil man gemerkt hat, dass für die meisten Workloads das besser passt als „0“. Solche Änderungen fließen on-premises oft nicht ein, um Abwärtskompatibilität zu wahren – daher liegt es am Admin, sinnvolle Defaults selbst zu setzen. Im Zweifelsfall lohnt ein Blick in aktuelle Best-Practice-Dokumente oder Whitepaper.

Zusammengefasst: Weder stumpf alles auf Werkseinstellungen lassen, noch jeden Regler ohne Not verschieben. Ein erfahrener DBA erkennt, wo Handlungsbedarf besteht. SQL Server bietet viele automatische Mechanismen, die einen Großteil der Optimierung übernehmen können – nutzen Sie diese, aber behalten Sie die Kontrolle über die wirklich wichtigen Schalter.

Auswirkungen schlechter Einstellungen auf Performance, Skalierbarkeit und Stabilität

Abschließend soll verdeutlicht werden, warum die richtige Konfiguration all dieser Aspekte so entscheidend ist. Fehlerhafte Einstellungen bei NUMA, MAXDOP & Co. wirken sich direkt und indirekt auf die Performance, Skalierbarkeit und Stabilität eines SQL Servers aus:

  • Performance-Einbußen: Suboptimale Parallelisierungseinstellungen führen dazu, dass Abfragen nicht mit voller Geschwindigkeit ausgeführt werden. Entweder dauern einzelne Queries unnötig lange (wenn Parallelität zu stark begrenzt oder falsch gesteuert ist) oder das System wird durch unnötige Nebenlast verlangsamt (wenn zu viele Threads und Kontextwechsel auftreten). Beispielsweise kann eine Abfrage mit schlechtem MAXDOP-Wert zehnmal länger laufen als nötig, weil sie nur einen Kern nutzt, obwohl acht zur Verfügung stünden. Umgekehrt könnte eine Flut von parallelen Mini-Abfragen die CPU in ständige Synchronisationsarbeit stürzen, sodass reale Arbeit liegen bleibt. Auch Memory-Einstellungen wirken hier: Wenn SQL Server ungezügelt den RAM vereinnahmt (Max Memory nicht gesetzt) und das OS anfängt zu swappen, bricht die Performance dramatisch ein. Ebenso verursachen NUMA-Fehlkonfigurationen latente Performanceprobleme – etwa ungleichmäßige CPU-Auslastung, suboptimale Cache-Nutzung und höheren Speicherzugriffsaufwand.
  • Schlechte Skalierbarkeit: Ein System skaliert, wenn es bei wachsender Last (mehr Nutzern, mehr Daten, komplexere Abfragen) proportionale Mehrleistung bringt. Falsche Einstellungen können Skaleneffekte verhindern. Beispiel: Auf einem schlecht konfigurierten SQL Server erreicht man vielleicht bei 4 gleichzeitigen Abfragen noch gute Antwortzeiten, aber bei 8 gleichzeitig gehen die Wartezeiten exponentiell hoch. Oft liegt das an zu aggressiver Parallelität (die Threads blockieren sich gegenseitig oder kämpfen um CPU), oder an zu restriktiver Parallelität (die Anfragen müssen nacheinander warten, statt gleichzeitig verschiedene Kerne zu nutzen). Eine ausgewogene MAXDOP/Cost-Threshold-Kombination dagegen sorgt dafür, dass auch bei höherer Concurrency jede Abfrage ihren Teil der Ressourcen effizient bekommt. NUMA-Aspekte beeinflussen die Skalierung vor allem bei höheren Prozessorzahlen: Eine Applikation, die auf 8 Kernen gut lief, könnte auf 32 Kernen sogar schlechter laufen, wenn das Thread-Management nicht angepasst wurde (Stichwort: Soft-NUMA nutzen, MAXDOP anpassen). Durch richtige Konfiguration kann man die Skalierbarkeit verbessern – das System bleibt berechenbar performant, auch wenn Last und Hardware wachsen.
  • Instabilität und Betriebsrisiken: Unter Stabilität versteht man hier konsistente Reaktionszeiten, Vermeidung von Ausnahmezuständen und insgesamt einen zuverlässigen Betrieb. Schlechte Einstellungen können zu sehr hohen Wartezeiten oder sogar Deadlock-ähnlichen Situationen führen. Beispielsweise kann zu hoher Parallelismus zu Thread Starvation führen: Alle Worker-Threads sind in Verwendung, neue Abfragen müssen warten (Fehler „Threadpool“ im Fehlerlog). Das System reagiert dann kaum noch, bis Threads frei werden – faktisch ein Stillstand der Verarbeitung. Auch Memory Overcommit kann instabil werden: Wenn das OS Speicher zurückfordert und SQL Server nicht darauf vorbereitet ist, kann es zu Out-of-Memory-Fehlern oder Notfallsituationen kommen (z.B. das OS killt Prozesse). Ein weiteres Beispiel: In virtuellen Umgebungen kann ständiges CPU-Stealing (VM wartet auf CPU) zu sporadischen Timeouts in der Anwendung führen – was aus Benutzersicht „instabil“ wirkt, weil mal geht es schnell, mal bricht es weg.

Richtig konfigurierte Systeme hingegen sind robust: Sie nutzen die Hardware bestmöglich aus, ohne an Grenzen zu stoßen. Die Performance ist im Rahmen des Möglichen optimal und vor allem vorhersehbar – Lastspitzen lassen sich abfedern, weil genug Reserve da ist oder weil das System dank passender Einstellungen nicht sofort in ineffizientes Verhalten kippt. Skalierung auf größere Datenmengen oder neue Hardware ist einfacher, wenn man weiß, dass z.B. MAXDOP schon passend eingestellt ist und nicht erst bei einem Hardware-Upgrade plötzlich auffällt, dass die Defaults bremsen.

Wirtschaftlich betrachtet bedeuten die richtigen Konfigurationen weniger Notfalleinsätze, weniger frustrierte Endanwender und optimal genutzte Ressourcen (man braucht ggf. weniger Hardware, wenn die vorhandene effizienter genutzt wird). Falsch konfigurierte SQL Server sind oft die „unsichtbaren Brandherde“ im Unternehmen – die Datenbank ist langsam, also schiebt man’s auf die Anwendung oder kauft teurere Hardware, während in Wahrheit ein paar Einstellungen das Problem lösen könnten.

Zusammenfassung der wichtigsten Punkte:

  • Vertrauen Sie darauf, dass SQL Server NUMA korrekt handhabt, aber sorgen Sie mit passenden MAXDOP-Einstellungen dafür, dass Abfragen nicht unnötig NUMA-Grenzen überschreiten.
  • Wählen Sie einen MAXDOP-Wert, der auf Ihre Kernanzahl und Workload abgestimmt ist; vermeiden Sie sowohl „0“ (unbegrenzt) auf großen Maschinen als auch „1“ (vollkommen seriell) ohne triftigen Grund.
  • Erhöhen Sie den Cost Threshold for Parallelism deutlich über den Default, damit nur wirklich lohnende Abfragen parallelisiert werden – das reduziert Overhead.
  • Erkennen Sie den relativen Wert von Hyper-Threading: Nutzen Sie ihn, aber beachten Sie seine Grenzen bei Kapazitätsplanung.
  • In virtuellen Umgebungen: Keine übermäßige Überbelegung von CPUs, aktivieren Sie vNUMA und fixieren Sie Speicher, sodass der SQL Server wie auf einem dedizierten Server läuft.
  • Nutzen Sie automatische Features klug, aber setzen Sie kritische Parameter manuell optimal.

Ein gut konfigurierter SQL Server wird performanter, skaliert sauber mit zunehmender Last und bleibt auch in Spitzenzeiten stabil im Verhalten. Die hier beschriebenen Mythen und Fehler treten in der Praxis häufig auf – doch mit dem Wissen um die Hintergründe lassen sie sich vermeiden. Im nächsten Abschnitt beantworten wir gängige Fragen (FAQ), die DBAs zu diesen Themen haben, um das Verständnis weiter zu vertiefen.

FAQ – Häufige Fragen und Antworten

Frage 1: Was ist NUMA und warum ist es für SQL Server relevant?
Antwort: NUMA steht für Non-Uniform Memory Access. Es bezeichnet eine Server-Architektur, bei der jeder CPU-Sockel seinen eigenen lokalen Speicher hat. Für SQL Server ist das relevant, weil Zugriffe auf lokalen RAM schneller sind als auf fremden RAM eines anderen Sockels. SQL Server erkennt NUMA automatisch und versucht, Abfragen und Speicherzugriffe pro NUMA-Knoten lokal zu halten, um die Performance zu optimieren. Wenn ein Server mehrere NUMA-Knoten hat, betreibt SQL Server für jeden Knoten getrennte Schedulers und Memory-Manager, was die Skalierbarkeit auf Multi-Socket-Systemen verbessert.

Frage 2: Erkennt SQL Server die NUMA-Architektur automatisch oder muss ich etwas manuell konfigurieren?
Antwort: SQL Server erkennt die NUMA-Architektur des Servers automatisch beim Start. Sie müssen in der Regel nichts manuell konfigurieren. Im Error-Log von SQL Server sieht man Einträge, die die erkannten NUMA-Knoten und zugehörigen CPU-Zuweisungen auflisten. Nur in seltenen Fällen – etwa bei sehr vielen CPUs ohne Hardware-NUMA oder speziellen Optimierungen – könnte man manuell Soft-NUMA konfigurieren. Aber standardmäßig ist keine manuelle Einstellung nötig; SQL Server ist „NUMA-aware by default“.

Frage 3: Was ist Soft-NUMA und sollte man es manuell einstellen?
Antwort: Soft-NUMA ist eine SQL-Server-Funktion, bei der der Server zusätzliche NUMA-Knoten softwareseitig definiert, um Ressourcen besser zu verwalten. Beispielsweise kann ein einzelner großer Hardware-NUMA-Knoten mit 32 CPUs in vier Soft-NUMA-Knoten à 8 CPUs aufgeteilt werden. Das kann interne Engpässe verringern (z.B. bei der Verteilung von I/O-Completion-Tasks oder Lazy Writer Threads). Seit SQL Server 2016 geschieht Automatic Soft-NUMA von selbst, wenn mehr als 8 Kerne pro Knoten vorhanden sind. Manuell sollte man Soft-NUMA nur konfigurieren, wenn man sehr spezifische Anforderungen hat und genau weiß, was man tut – etwa wenn automatische Partitionierung ungünstig ausgefallen ist. In den meisten Fällen muss man Soft-NUMA nicht manuell einstellen, da der Server es automatisch sinnvoll macht.

Frage 4: Was bedeutet „Max Degree of Parallelism (MAXDOP)“?
Antwort: MAXDOP bestimmt, wie viele CPU-Kerne maximal für die Ausführung einer einzelnen Abfrage verwendet werden dürfen. Einfach ausgedrückt: Es limitiert den Grad der Parallelität pro Query. Ein MAXDOP von 4 erlaubt z.B., dass eine Abfrage bis zu 4 Threads gleichzeitig (auf 4 Kernen) nutzt. Der Standardwert 0 bedeutet „unbegrenzt“ – der SQL Server kann so viele Kerne nehmen, wie vorhanden sind (bis zu 64 in aktuellen Versionen). MAXDOP wirkt sich also direkt auf parallele Abfragen aus: hohe Werte ermöglichen breitere Parallelisierung, niedrige Werte beschränken Abfragen auf wenige oder einen Kern.

Frage 5: Wie finde ich den optimalen MAXDOP-Wert für meinen Server?
Antwort: Der optimale MAXDOP hängt von Ihrer Hardware und Workload ab. Ein guter Startpunkt ist, die Anzahl logischer Prozessoren pro NUMA-Knoten als Obergrenze zu nehmen (maximal jedoch 8 oder 16). Beispiel: Bei 2 CPUs mit je 10 Kernen (20 logische mit HT pro Sockel) wäre eine MAXDOP-Einstellung von 8 oder 10 sinnvoll, um eine Query innerhalb eines Sockels zu halten. Für einen einzelnen Sockel mit 6 Kernen würde man MAXDOP 6 setzen (bzw. 6 oder darunter). Microsoft gibt Tabellen mit Empfehlungen heraus (oft: <=8 Kerne -> MAXDOP = #Kerne, >8 Kerne -> MAXDOP = 8, bei mehreren Knoten >16 logische pro Knoten -> halbieren). Letztlich sollten Sie aber messen: Beobachten Sie Ihr System mit verschiedenen MAXDOP-Einstellungen. Prüfen Sie, wie sich Abfrage-Laufzeiten und Wait-Statistiken verändern. Der optimale Wert ist erreicht, wenn Ihre schweren Abfragen zügig laufen, aber die Gesamtlast stabil bleibt (keine übermäßigen CXPACKET-Waits, kein Threadpool-Anstieg etc.). Viele OLTP-DBAs landen bei Werten zwischen 4 und 8; viele BI/Reporting-DBAs bei Werten zwischen 8 und 16.

Frage 6: Warum ist der Standardwert MAXDOP 0 (unbegrenzt) problematisch?
Antwort: MAXDOP 0 erlaubt es dem SQL Server, alle verfügbaren CPUs für eine einzelne Abfrage einzusetzen. Auf modernen Systemen mit z.B. 32 oder 64 logischen Prozessoren kann das zu Über-Parallelisierung führen – sprich, eine Query benutzt unnötig viele Threads. Das kann mehr Schaden anrichten (durch Koordinations-Overhead) als Nutzen bringen. Zudem können bei MAXDOP 0 mehrere gleichzeitige Abfragen sich gegenseitig die CPU wegnehmen, weil jede denkt, sie darf alles nutzen. Das führt oft zu hohen Kontextwechseln, Synchronisations-Waits (CXPACKET) und im Worst Case zu Thread-Verarmung (THREADPOOL Waits), wenn extrem viele Threads erzeugt werden. Kurz: Der Default 0 ist nicht optimal für die meisten Produktionsumgebungen, außer bei sehr wenigen Kernen. Darum sollte man MAXDOP auf einen sinnvollen Wert begrenzen, der zur Hardware passt, um das System im Gleichgewicht zu halten.

Frage 7: Sollte man MAXDOP in manchen Fällen auf 1 setzen (Parallelität ausschalten)?
Antwort: MAXDOP = 1 bedeutet, Parallelität komplett zu deaktivieren (alles läuft seriell). Das sollte nur in Ausnahmefällen gemacht werden. Beispielsweise erfordert SharePoint aus Kompatibilitätsgründen MAXDOP 1, weil seine Abfragen sonst ineffizient parallel laufen könnten. Ein anderes Szenario könnten sehr hohe Benutzerzahlen mit ultraschnellen Einfachanfragen sein – hier kann parallele Ausführung mehr stören als nützen, da ohnehin alles in Millisekunden passiert. Generell aber gilt: Für die meisten Workloads bringt es Vorteile, bestimmte Abfragen parallel laufen zu lassen (Datenbanken sollen ja gerade mehrere Kerne nutzen können). MAXDOP 1 kann zwar Probleme mit schlecht parallelisierten Abfragen lösen (z.B. wenn eine Query immer das ganze System lahmlegt, könnte man testweise auf 1 gehen), doch meist ist der bessere Ansatz, MAXDOP etwas höher (2,4,…) zu wählen oder die problematische Query gezielt zu optimieren. Also: MAXDOP 1 als Dauerlösung eher nein, außer es liegt eine vom Hersteller dokumentierte Notwendigkeit vor.

Frage 8: Was ist der „Cost Threshold for Parallelism“?
Antwort: Das ist eine Serverweite Einstellung, die definiert, ab welchem geschätzten Kostenwert eine Abfrage als „parallelisierungswürdig“ gilt. Der Wert (Standard 5) bezieht sich auf die interne Kostenberechnung des Optimierers. Wenn die geschätzten Kosten eines Abfrageplans über diesem Schwellwert liegen, dann erwägt der Optimierer parallele Pläne (unter Berücksichtigung von MAXDOP etc.). Liegt der Kostenwert darunter, wird die Abfrage seriell ausgeführt – selbst wenn theoretisch mehrere CPUs frei wären. Der Cost Threshold acts also als Trigger, welche Abfragen parallel ausgeführt werden dürfen und welche nicht.

Frage 9: Ist der Standardwert 5 für den Cost Threshold for Parallelism noch zeitgemäß?
Antwort: Nein, in den allermeisten Fällen ist 5 viel zu niedrig für heutige Systeme. Dieser Wert wurde vor langer Zeit festgelegt, als Hardware deutlich schwächer war. Heute können Abfragen mit Kosten >5 oft problemlos auf einem Kern laufen. Der Standardwert führt deshalb dazu, dass fast jede etwas komplexere Abfrage sofort parallelisiert wird. Experten sind sich einig, dass man diesen Wert anheben sollte – 5 gilt als veraltet. In Cloud-Umgebungen und neuen Empfehlungen sieht man oft Startwerte wie 50. Microsoft selbst sagt: der Default 5 ist ein Ausgangspunkt, aber kein empfohlener Wert. Also: Ja, 5 ist in vielen Szenarien zu niedrig und sollte angepasst werden.

Frage 10: Wie bestimme ich einen sinnvollen Cost-Threshold-Wert?
Antwort: Ein Ansatz ist es, mit einem moderaten Wert wie 20 oder 25 anzufangen, zu beobachten, und dann ggf. weiter zu erhöhen. Viele DBAs nutzen heute 50 als pauschalen Tipp, was oft gut funktioniert. Genau genommen hängt der ideale Wert von Ihrer Workload ab: Man kann sich zum Beispiel Abfragepläne anschauen und deren geschätzte Kosten notieren. Finden Sie heraus: Welche Kosten haben typische Abfragen, die gerade noch schnell laufen? Diese sollten idealerweise unter dem Schwellenwert liegen, damit sie nicht parallelisiert werden. Welche Kosten haben die Abfragen, die spürbar länger dauern? Diese sollten über dem Threshold liegen, damit sie parallel laufen können. Wenn beispielsweise viele kleine OLTP-Abfragen Kosten im Bereich 10-20 haben, wäre ein Threshold über 20 ratsam. Oder wenn Sie OLAP-Queries mit Kosten 100+ haben, möchten Sie ab vielleicht 50 oder 80 parallelisieren. In der Praxis hat es sich bewährt, mit 50 als Richtgröße zu arbeiten – und dann eventuell feinzutunen: Bei immer noch zu vielen parallelen Miniplänen weiter rauf (60, 70…), bei zu wenigen parallelisierten großen Plänen etwas runter (40). Wichtig: Änderungen immer schrittweise und Wirkung prüfen (z.B. Anzahl CXPACKET-Waits, CPU-Auslastungsmuster).

Frage 11: Wie hängen MAXDOP und Cost Threshold for Parallelism zusammen?
Antwort: Sie bestimmen gemeinsam das Parallelverhalten. Der Cost Threshold entscheidet, ob eine Abfrage parallel ausgeführt werden darf, und MAXDOP bestimmt, wie viele Kerne sie dabei maximal nutzen kann. Man kann es so sehen: Zuerst vergleicht der Optimierer die geschätzten Kosten mit dem Threshold. Wenn Kosten < Threshold, wird die Abfrage zwangsläufig seriell ausgeführt (unabhängig von MAXDOP). Wenn Kosten >= Threshold, wird ein paralleler Plan in Betracht gezogen – jetzt kommt MAXDOP ins Spiel, um die Obergrenze der Threads festzulegen. Beide Parameter sollten aufeinander abgestimmt sein. Beispiel: Wenn man MAXDOP streng auf 2 setzt, aber den Threshold bei 5 lässt, werden zwar wenige Threads genutzt, aber noch immer fast alle Abfragen ab Kosten 5 parallel (eben mit 2 Threads). Das könnte immer noch unnötig sein. Oder andersrum: Wenn man den Threshold hoch auf 100 setzt, aber MAXDOP 16 offenlässt, passiert folgendes – nur sehr teure Abfragen parallelisieren, die nehmen dann aber bis zu 16 Kerne. Das kann okay sein, weil wirklich nur große Queries betroffen sind. Wichtig ist, dass beide Parameter dem Workload angepasst sind: Der Threshold filtert welche Abfragen parallel gehen – MAXDOP begrenzt deren Ausmaß. In vielen Best Practices wird betont, diese Einstellungen gemeinsam zu betrachten und zu konfigurieren, um das gewünschte Parallelisierungsniveau zu erreichen.

Frage 12: Woran erkenne ich, dass meine Parallelisierungs-Einstellungen suboptimal sind?
Antwort: Ein paar Anzeichen im laufenden Betrieb können auf falsche Parallel-Einstellungen hindeuten: – Wartestatistiken: Führen Sie regelmäßig sys.dm_os_wait_stats aus (oder nutzen Monitoring-Tools). Wenn dort CXPACKET oder CXCONSUMER ganz oben stehen als Wait-Typen, bedeutet das, dass viele Abfragen auf parallele Synchronisation warten – ein Indikator, dass vielleicht zu viel parallelisiert wird (hoher Thread-Overhead). In neueren SQL Versionen wurden CXPACKET aufgesplittet, aber grundsätzlich deutet eine Überdominanz dieser Waits auf Tuning-Bedarf bei MAXDOP/Threshold hin. Auch THREADPOOL-Waits sind alarmierend – sie heißen, Threads gehen aus, was oft an zu hohen parallelen Anforderungen liegt. SOS_SCHEDULER_YIELD häufig bedeutet, viele Threads konkurrieren um CPU-Zeit, was auf suboptimale Parallelverteilung hindeuten kann. – CPU-Auslastung und Kern-Verteilung: Schauen Sie, ob Ihre CPU-Kerne gleichmäßig genutzt werden. Bei schlechten Einstellungen sieht man manchmal ein Muster, wo nur ein Kern hoch auslastet (könnte auf MAXDOP 1 oder zu hohen Threshold hindeuten) oder alle Kerne ständig auf 100% rennen (könnte auf MAXDOP 0 + viele parallele Abfragen hindeuten). – Abfrage-Performance: Werden bestimmte Abfragen bei Last unverhältnismäßig langsam? Beispiel: Eine Abfrage dauert alleine ausgeführt 5 Sekunden, aber wenn 5 Nutzer sie gleichzeitig starten, dauert jede plötzlich 30 Sekunden. Das kann ein Zeichen sein, dass sie sich gegenseitig ins Gehege kommen mit parallelen Threads (oft wegen zu hoher MAXDOP, so dass 5 Abfragen 40 Threads starten, die dann sch in die Quere kommen). Auch ungleichmäßige Performance – mal läuft die selbe Query blitzschnell, mal ewig – kann auf suboptimale Parallelität hinweisen, insbesondere wenn es vom Gesamtsystemzustand abhängt. – Query Store / Ausführungspläne: Im Query Store (falls aktiviert) kann man sehen, ob es viele Downgrades gibt – z.B. parallel geplante Abfragen, die bei Ausführung doch reduziert wurden. Oder ob DOP Feedback greift (SQL 2022+), was darauf hinweist, dass der Server Ihre DOP-Einstellung oft korrigieren muss (dann war die globale evtl. nicht ideal).

Kurz gesagt: Häufige CPU-Waits (CXPACKET, SCHEDULER_YIELD), hohe CPU trotz wenig Durchsatz, oder sehr volatile Abfrage-Laufzeiten sind Indizien. Dann sollten Sie Ihre MAXDOP- und Threshold-Werte überprüfen.

Frage 13: Was ist Hyper-Threading und wie beeinflusst es SQL Server?
Antwort: Hyper-Threading (Intel) bzw. Simultaneous Multithreading (AMD) ist eine Prozessor-Technologie, bei der ein physischer Kern zwei (oder mehr) logische Prozessoren zur Verfügung stellt. Das heißt, das Betriebssystem und damit SQL Server „sehen“ doppelt so viele CPU-Einheiten. Der Hauptvorteil ist, dass der Prozessor effizienter ausgelastet wird – wenn ein Thread im Kern auf eine Ressource wartet, kann ein zweiter Thread diese ausnutzen. Für SQL Server bedeutet das: Er erhält mehr Scheduler-Threads und kann potenziell mehr gleichzeitige Work erledigen, aber jeder einzelne Thread wird auf einem Hyper-Thread nicht so leistungsfähig sein wie auf einem eigenen physischen Kern (weil sich beide logischen Threads ja die Kern-Ressourcen teilen). Im Durchschnitt bringt Hyper-Threading vielleicht 20-30% mehr Durchsatz. SQL Server ist so gebaut, dass er Hyper-Threads nutzen kann, aber er behandelt sie nicht identisch wie separate Kerne – z.B. bei bestimmten Berechnungen (Kaskadierende Scans etc.) wird berücksichtigt, dass zwei logische CPU auf demselben Kern nicht doppelte Leistung haben. Insgesamt beeinflusst HT den SQL Server also positiv in Sachen Parallelität und Durchsatz, erfordert aber beim Zählen der „Kerne“ etwas Vorsicht (man hat eben virtuelle Kerne). Man sollte Hyper-Threading bei Lizenzierung/Edition auch bedenken: Standard Edition z.B. ist limitiert auf 24 Kerne – hier zählen Hyper-Threads als Kerne. D.h. auf einer 12-Kern-CPU mit HT hätte man 24 logische – das passt gerade ins Limit. Hätte man HT aus, könnte man theoretisch 24 physische Kerne nutzen, was mehr Rechenleistung wäre, aber das Limit wäre überschritten. Solche Überlegungen gehören dazu. Rein technisch: HT verbessert die Fähigkeit von SQL Server, viele gleichzeitige Sessions zu bedienen, hat aber wenig Effekt auf die Beschleunigung einer einzelnen Abfrage (das macht eher MAXDOP mit echten Kernen).

Frage 14: Soll man Hyper-Threading für SQL Server deaktivieren, um die Leistung zu verbessern?
Antwort: In der Regel nein. Die meisten SQL-Server-Deployments laufen mit Hyper-Threading, weil es mehr Vorteile als Nachteile bringt. Das Deaktivieren könnte in sehr speziellen Fällen sinnvoll sein – zum Beispiel, wenn man extrem latenzkritische Einzel-Threads hat und sicherstellen will, dass jeder Kern nur an einem Thread arbeitet. Einige alte Empfehlungen (vor vielen Jahren) rieten unter bestimmten Umständen dazu, aber moderne SQL Server Versionen und moderne CPUs kommen mit HT sehr gut klar. Behalten Sie HT an, außer Sie haben nachweislich eine Situation, wo es stört. Beispielsweise wenn Sie per Test feststellen, dass unter Vollast die Hyper-Threads nur noch Kontextwechsel erzeugen aber kaum mehr Durchsatz – das wäre ungewöhnlich, aber in HPC-artigen Workloads möglich. Im Normalfall skaliert SQL Server aber besser mit HT an. Zu bedenken ist: Durch HT sinkt die Rechenleistung pro Thread minimal, weil ein zweiter Thread mitschnurrt; aber die Gesamt-Work pro Zeit steigt. Es kann allerdings unschöne Effekte geben, wenn zu viele Prozesse auf demselben physischen Kern landen – was aber das OS/SQL eigentlich zu steuern versucht. Mein Ratschlag: Lassen Sie HT aktiv, optimieren Sie lieber MAXDOP und Co. Wenn Sie CPU-Probleme haben, fügen Sie eher mehr Kerne (oder schnellere) hinzu oder schauen Sie ins Tuning der Abfragen. Das Abschalten von Hyper-Threading ist als Tuning-Maßnahme ziemlich drastisch und meist überflüssig.

Frage 15: Was ist der Unterschied zwischen physischen Kernen und logischen Prozessoren?
Antwort: Physische Kerne sind die tatsächlichen Verarbeitungseinheiten auf dem CPU-Chip. Logische Prozessoren umfassen die physischen Kerne plus eventuelle Hyper-Threading-Einheiten. Beispiel: Ein Server hat 2 CPU-Sockel, jeder mit 8 physischen Kernen und Hyper-Threading aktiviert – dann hat das Betriebssystem 2×8×2 = 32 logische Prozessoren. Ohne Hyper-Threading wären es nur 16 logische (was dann identisch zu den physischen Kernen wäre). Für SQL Server-Lizenzierung und viele Konfigurationsfragen sind physische Kerne die relevante Größe, da sie die eigentliche Rechenleistung darstellen. Die logischen zeigen, wie viele Thread-Kontext das OS verwalten kann. In Windows Task-Manager werden logische Prozessoren angezeigt. In SQL Server-DMVs wie sys.dm_os_schedulers sieht man ebenfalls alle Scheduler, auch die, die Hyper-Threads repräsentieren (dort gibt es eine Spalte is_online und status etc., woran man primäre vs. sekundäre Threads erkennen kann). Kurz: Physisch = echte Kerne; logisch = alles, was das OS als CPU ausweist (Hyper-Threads inklusive).

Frage 16: Wie kann ich herausfinden, wie viele NUMA-Knoten mein SQL Server nutzt?
Antwort: Es gibt mehrere Wege: – SQL Server Errorlog: Beim Start protokolliert SQL Server Informationen wie „Node configuration: node 0: X CPUs, node 1: Y CPUs…“. Dort sieht man die NUMA-Aufteilung. – DMV sys.dm_os_nodes: Diese gibt pro Knoten eine Zeile aus (z.B. Knoten 0 und 1 für zwei Knoten). Sie zeigt u.a. memory_node_id, node_state etc. Daraus kann man die Anzahl Knoten ersehen und ob sie online sind. – DMV sys.dm_os_schedulers: Hier gibt es die Spalte parent_node_id. Wenn Sie diese gruppieren, sehen Sie, wie viele Scheduler pro Node registriert sind, was indirekt die Knotenanzahl und CPU-Verteilung zeigt. – Windows-Betriebssystem: Im Task-Manager unter „Prozessor“ kann man die Ansicht nach NUMA-Knoten gruppieren, wenn vorhanden. Auch via PowerShell oder COREINFO-Tool kann man die NUMA-Topologie auslesen.

In einer VM, falls vNUMA aktiv ist, meldet Windows entsprechend mehrere Knoten. Wenn vNUMA aus ist, sieht Windows alles als einen Knoten (auch wenn physisch verteilt). Also ideal ist, sys.dm_os_nodes zu prüfen – was dort als Node 0, 1 etc. aufgeführt ist, nutzt SQL Server auch so.

Frage 17: Worauf muss man bei SQL Server in einer virtuellen Maschine (VM) achten?
Antwort: Auf einiges – im Prinzip muss man zusätzlich zur normalen SQL-Konfiguration die Hypervisor-Aspekte bedenken. Wichtige Punkte: – vCPU zu pCPU Verhältnis: Stellen Sie sicher, dass die VM genügend physische Ressourcen hat. D.h. möglichst 1:1-Zuordnung oder nur moderate Überbelegung. Achten Sie auf Host-Seite auf CPU-Ready-Zeiten. – vNUMA: Wenn die VM viele vCPUs hat (mehr als ein Sockel auf dem Host Kerne hat), aktivieren bzw. erlauben Sie vNUMA, damit SQL Server die Aufteilung kennt. – Speicher: Geben Sie der VM fest zugewiesenen RAM, ohne Balloning/Dynamik. Setzen Sie in SQL Server Max Memory etwas unter dem VM-RAM, damit Windows in der VM Reserven hat. – Storagelatenz: Virtualisierung kann Latenzen erhöhen, nutzen Sie paravirtualisierte Treiber (z.B. VMware PVSCSI) und stellen Sie sicher, dass die virtuellen Disks auf performantem Storage liegen. – Zeitsynchronisation und CPU-Kontrolle: In VMware z.B. kann man „Latency Sensitivity“ hochsetzen für kritische VMs, was den Planer begünstigt. Auch die Energieeinstellungen: Host und VM sollten auf Hochleistung stehen. – Sicherung und Maintenance: Der SQL Server in der VM braucht genauso Backups, Indexpflege etc. – Virtualisierung ändert daran nichts. Vorsicht aber mit Snapshots: Lange offene VM-Snapshots können SQL-IO bremsen. – Integration Services: Deaktivieren Sie in Hyper-V beispielsweise „Betriebssystem herunterfahren“ oder „Datenaustausch“ nicht unbedingt, aber achten Sie auf Backup Tools, die VSS auslösen – das kann Freeze in SQL verursachen, falls schlecht konfiguriert.

Kurz: Man muss in VM-Umgebungen ganzheitlich denken. Die oben im Artikel genannten Fehler (CPU Overcommit, Memory Ballooning etc.) vermeiden. So läuft SQL Server in der VM fast wie auf physischem Host.

Frage 18: Wie viele vCPUs sollte eine SQL-Server-VM bekommen?
Antwort: So viele wie nötig, aber so wenige wie möglich – salopp gesagt. Man orientiert sich idealerweise an den physischen Kernen, die man wirklich bereitstellen kann. Eine gute Praxis ist: Pro VM nicht mehr vCPUs als ein NUMA-Knoten des Hosts hat, um optimale Leistung zu bekommen. Beispiel: Host hat 2×10 Kerne. Dann einer VM maximal 10 vCPUs geben, damit sie schön in einen Sockel passt (plus vNUMA off bleibt). Wenn die SQL-VM wirklich mehr Power braucht als 10 Kerne, dann natürlich mehr geben, aber dann vNUMA an. Wichtig ist, nicht unnötig viele vCPUs zu vergeben „weil man kann“. Jede vCPU bedeutet im Hypervisor mehr Scheduling-Aufwand. Und wenn SQL Server viele vCPUs sieht, verteilt er Threads auf alle – was aber, falls die Hardware nicht mithält, zu Wartezeiten führt. Ein Indikator ist die CPU-Auslastung: Wenn eine VM mit 16 vCPU nie über z.B. 20% Gesamt-CPU geht, nutzt sie effektiv vielleicht nur 3-4 Kerne – man hätte ihr also nicht so viele geben müssen. Andersherum: Geht sie oft auf 80-90%, braucht sie vielleicht mehr vCPUs (wenn verfügbar) oder schnellere CPU. Allgemein gilt: Right-Sizing. Starten mit einer realistischen Kernzahl (vielleicht 4, 8, 12 je nach erwarteter Last), dann beobachten. Für große Enterprise-SQL-Workloads sind auch 32 vCPUs oder mehr machbar, aber dann sollte man idealerweise dedizierte Host-Ressourcen einplanen.

Frage 19: Ist es in Ordnung, auf dem Host mehr vCPUs zu vergeben als physische Kerne vorhanden sind (Overcommit)?
Antwort: Leichte Überprovisionierung ist in vielen Virtualisierungsumgebungen üblich (z.B. 1,5x so viele vCPUs wie echte Kerne). Aber für einen kritischen SQL Server sollte Overcommit vermieden oder minimal gehalten werden. Overcommit bedeutet, dass wenn mehrere VMs gleichzeitig Last ziehen, nicht genug physische Kerne für alle Threads gleichzeitig da sind – der Hypervisor muss time-slicen. Das führt zu erhöhten Latenzen (die VMs warten auf CPU). Besonders schlimm wird es, wenn eine VM viele vCPUs hat, denn sie bekommt nur CPU-Zeit, wenn der Hypervisor so viele physische Kerne gleichzeitig frei hat. Bei hohem Overcommit kann es sein, dass der Hypervisor selten ein Zeitfenster findet, um z.B. alle 16 vCPUs einer VM parallel zu schedulen – dann sieht die VM trotz verfügbarer Gesamtleistung nur wenig parallele Ausführung. Im Ergebnis stottert der SQL Server. Deshalb: Wenn möglich, geben Sie pro Host nicht wesentlich mehr vCPUs raus, als Kerne vorhanden sind. In Produktionsumgebungen mit SQL und anderen Schwergewichten wird oft 1:1 oder 2:1 (max) empfohlen. Wenn Overcommit, dann mit Bedacht: Reservieren Sie evtl. der SQL-VM einen gewissen Anteil, oder priorisieren Sie sie (z.B. mit höheren Shares/Weight). Overcommit ist okay, solange die Summe der gleichzeitig benötigten Kerne nicht über 100% der physischen geht – was man aber nie genau vorhersagen kann. Also besser: So gering wie möglich halten für SQL-Workloads.

Frage 20: Sollte man für SQL Server dynamische Speicherzuweisung (Memory Overcommit oder Ballooning) verwenden?
Antwort: Nein, das sollte man vermeiden. Dynamische RAM-Zuweisung (z.B. Hyper-V Dynamic Memory) oder VMware Ballooning holen sich Speicher von der VM zurück, wenn er scheinbar ungenutzt ist. SQL Server neigt aber dazu, seinen zugeteilten Speicher komplett auszufüllen (Buffer Pool). Selbst wenn gerade nicht alle Seiten gebraucht werden, hält er sie als Cache. Ein Hypervisor könnte denken „oh, da ist viel ungenutzter Speicher, den nehme ich mal weg“. Dann fehlt dem SQL Server plötzlich Cache – er muss Daten wieder von der langsamen Platte holen, Performance sinkt, vielleicht wird sogar ausgelagert. Das ist kontraproduktiv. Darum sollen produktive SQL-Server-VMs fest zugewiesenen Speicher haben, auf den kein anderer zugreift. Man kann natürlich Overcommit auf Host-Ebene betreiben, aber das ist noch gefährlicher als CPU-Overcommit, weil Memory-Overcommit zu Disk-Swapping führt, was enorm langsam ist. Also: Kein dynamischer RAM für SQL VMs. Lieber der VM etwas weniger geben, falls man sparen muss, aber das dann fest allozieren. Und innerhalb der VM wie erwähnt Max Memory config so setzen, dass Windows Reserve hat.

Frage 21: Welche SQL-Server-Einstellungen sollte man immer manuell anpassen?
Antwort: Es gibt ein paar Einstellungen, die fast universell angepasst werden sollten: – Max Degree of Parallelism (MAXDOP): Wie ausführlich besprochen, sollte je nach Kernanzahl und Workload ein passender Wert statt 0 gesetzt werden. – Cost Threshold for Parallelism: Ebenfalls meist hochsetzen (z.B. 50 statt 5). – Max Server Memory: Nie unbegrenzt lassen. Setzen Sie einen Wert, so dass das OS ~10% RAM (oder mindestens 2-4 GB) übrig hat. Bei reinen DB-Servern kann SQL gern 80-90% des RAMs bekommen, aber es muss eine Grenze definiert sein. – TempDB-Konfiguration: Anzahl Dateien und ggf. Initialgröße/Autogrowth. Faustregel: 1 Datei pro 4 Kerne (physisch), max. 8 oder 16 Dateien. Autogrowth in feste MB-Schritte (nicht Prozent). In SQL 2016+ wird bei Installation oft schon auf 8 Dateien gestellt, aber prüfen und anpassen schadet nicht. – Dateiautogrowth allgemein: Für alle DBs (inkl. TempDB) sinnvolle Autogrowth-Werte setzen, um viele kleine Wachstums-Schritte und Fragmentierung zu vermeiden. Und Auto-Shrink deaktivieren (ist default eh off, aber sicherstellen). – Recovery Model (falls nötig) und Backup-Pläne entsprechend: Nicht direkt Performance, aber wichtig für Admin – z.B. OLTP meist Full Recovery mit Log-Backups, etc. – Energieoptionen: Am Serverbetriebssystem das Energieschema auf Höchstleistung setzen (gerade bei Windows Standard wird manchmal auf „Ausbalanciert“ gelassen, was CPU drosseln kann). – optimize for ad hoc workloads: Diese Option auf „1“ setzen, um zu verhindern, dass für jede einmalig ausgeführte Abfrage ein voller Plan im Cache bleibt. Dadurch wird der Plan Cache effizienter genutzt (gerade wenn viele Ad-hoc-Queries aus einer Applikation kommen). – backup compression default: Auf „1“ setzen, damit SQL Backups standardmäßig komprimiert werden (spart Zeit und Speicherplatz in den meisten Fällen, minimal mehr CPU, die oft übrig ist). – remote query timeout evtl. hochsetzen oder auf unendlich, wenn Distributed Queries genutzt und Standard (600s) nicht reicht – Umgebungsabhängig. – Falls Enterprise Edition: Features wie memory-optimized tempdb metadata (SQL 2019) einschalten, falls relevant, oder andere Optionen, die Performance helfen (z.B. in 2022 Parameter Sensitivity Plan einschalten – wobei das Teil von Intelligent QP und default ON ist).

Die wichtigsten sind jedoch MAXDOP, Cost Threshold, Memory und TempDB – diese vier sollte praktisch jeder DBA nach Installation angehen.

Frage 22: Welche Einstellungen kann man meistens auf den Standardwerten belassen?
Antwort: Viele der über 100 Server-Konfigurationsoptionen müssen tatsächlich nie angerührt werden. Dazu gehören: – max worker threads: Standard 0 lässt SQL automatisch verwalten. Nur in extremen Spezialfällen (sehr viele CPUs >64) könnte man überlegen, aber in 99% bleibt das auf 0. – affinity mask / affinity I/O mask: Standard (automatisch alle CPUs nutzen) ist fast immer korrekt. Manuell CPU-Affinität zu setzen ist veraltet und kann mehr Probleme machen. – priority boost: Sollte immer aus bleiben (Standard ist 0 = aus). Das Feature ist deprecated, es bringt selten was und kann dem OS schaden. – parallelism wait at low priority Flags etc.: Alles was experimentell oder speziell ist, lieber default lassen. – Auto-Statistiken: auto create statistics und auto update statistics sollten auf ein (on) bleiben – Standard ist on. Man lässt das an, außer man hat sehr gute Gründe. – auto close, auto shrink: Diese sind standardmäßig off (zumindest für normale DBs), so lassen. (Manche Tools oder Express setzen auto close on – dann sollte man es abschalten für Performance). – fill factor (Server-Default): Kann meist 0 (bzw. 100%) bleiben, es sei denn, man weiß, dass die Workload stark fragmentierende Updates hat, dann evtl. individuell pro Index. – max degree of parallelism auf Datenbank- oder Abfrageebene: In der Regel regelt man parallel auf Server-Ebene. Datenbank-scoped MAXDOP oder Query-Hints nur bei Bedarf. Standard (keine extra Limits auf DB-Ebene) passt. – TempDB is memory optimized (2019 Feature): Standard aus. Nur einschalten falls intensive TempTable-Nutzung zu Metadata-Locks führt (selten). – query store: Ab SQL 2016 Standard an (im neuen DB). Das kann man anlassen – es schadet selten, eher nützlich. – lightweight pooling (Fiber Mode): Standard off – fast nie aktivieren, es sei denn in extrem CPU-Bound ohne Context Switch Overhead (selten angebracht). – columnstore insert mode etc.: Meist standard belassen, solche speziellen Options muss man nur anfassen, wenn man genau das Feature nutzt und Optimierung braucht. – backup checksum default: Standard off – kann man überlegen anzuschalten, aber Standard off ist okay, weil es minimal Overhead hat. Hier streiten sich die Geister; aber Performance-sicht Standard ok.

Im Grunde sind viele Defaults vernünftig. Schwerpunkt für Änderungen: Parallelismus, Memory, TempDB. Der Rest: wenn kein Problem sichtbar, nicht anfassen.

Frage 23: Gibt es automatische Optimierungen in SQL Server für Parallelität, so dass man weniger manuell einstellen muss?
Antwort: Ja, es gibt einige neuere Features: – Automatische MAXDOP-Empfehlung bei Installation: Der SQL-Setup schlägt inzwischen auf Basis der CPU-Anzahl einen MAXDOP vor. Aber das ist einmalig beim Install und nicht dynamisch – es hilft lediglich, gleich einen vernünftigen Startwert zu setzen. – Intelligent Query Processing – DOP Feedback: In SQL Server 2022 wurde „Degree of Parallelism Feedback“ eingeführt. Das bedeutet: Wenn eine Abfrage wiederholt ausgeführt wird und der SQL Server feststellt, dass die gewählte DOP (z.B. 8 Threads) ineffizient war (z.B. weil Threads viel leerliefen oder Wartezeiten entstanden), dann kann er für zukünftige Ausführungen automatisch die DOP senken (oder auch erhöhen, in manchen Fällen) – und das getrennt pro Abfrage. Dieses Feature kann also zur Laufzeit Parallelität anpassen ohne DBA-Eingriff, allerdings greift es nur für wiederkehrende Abfragen mit konstantem Plan und benötigt Query Store aktiviert. Es ist eine sinnvolle Ergänzung, behebt aber nicht grundsätzlich falsche globale Einstellungen. – Adaptive Grant und Adaptive Join: Auch Teil von Intelligent QP (ab 2017/2019). Sie ändern nicht DOP, aber z.B. kann ein Batch-Mode-Plan während der Ausführung entscheiden, bei wenig Daten doch in seriellen Modus zu gehen etc. Das hilft ein bisschen, suboptimale Parallelentscheidungen aufzufangen. – Auto-Tuning in Azure: In Azure SQL Datenbank werden manche Einstellungen automatisch gemanagt (z.B. MAXDOP default 8, keine Cost-Threshold-Einstellung aber Microsoft auto-tunet auf Plattformebene gewisse Dinge). Auf VM/On-Prem muss man selber tunen. – Resource Governor mit Classified Workloads: Eher manuell, aber man könnte verschiedene Workloads mit unterschiedlichen MAXDOP-Werten ausstatten (z.B. Reports DOP 8, OLTP DOP 2). Das ist aber Administrator-Aufwand, nicht automatisch. – Auto Pilot von Queries: SQL 2019+ hat „Memory Feedback“, „TempDB Feedback“ etc., aber nichts, was global automatisch MAXDOP oder Cost Threshold ändert.

Kurz gesagt: Es gibt Mechanismen, die auf Abfrageebene nachregeln (DOP Feedback), aber einen globalen, sich selbst optimierenden Parallelism-Tuner gibt es so (noch) nicht on-premises. Deswegen muss man die Basis-Konfiguration nach wie vor manuell setzen. Die automatischen Features verringern dann das Risiko, dass einzelne Abfragen komplett neben der Spur laufen.

Frage 24: Was passiert, wenn MAXDOP zu hoch eingestellt ist?
Antwort: Wenn MAXDOP zu hoch ist (z.B. 16 oder 0 auf einem 64-Core-System), können folgende Dinge passieren: – Einzelne Abfragen nutzen extrem viele Threads: Dadurch steigt der Verwaltungsaufwand. Threads müssen Ergebnisse mergen, Synchronisationspunkte (Exchanges) warten bis alle Threads fertig sind usw. Oft sieht man dann, dass die Abfrage trotz vieler Threads nicht proportional schneller wird – manchmal wird sie sogar langsamer als mit weniger Threads. – Mehr Konkurrenz zwischen Abfragen: Wenn viele Abfragen parallel laufen und jede zu viele Threads bekommt, laufen schnell hundert oder mehr aktive Threads, die sich gegenseitig aufhalten. Das kann zu allgemeiner Verlangsamung führen – alle CPUs immer voll, aber keine einzelne Query wird wirklich flott fertig. – Thread-Auslastungsspitzen: In Spitzenzeiten könnte der Thread-Pool erschöpft werden. SQL Server hat eine Grenze (z.B. standardmäßig ~512 Worker-Threads bei 16 CPUs, skaliert hoch bei mehr CPUs). Wenn ein Parallelplan z.B. 32 Threads will und 20 solcher Anfragen kommen, wären 640 Threads nötig – das übersteigt die verfügbaren Worker und SQL Server muss einige Abfragen drosseln (sogenanntes Thread-Yielding, Abfragen warten auf freie Worker oder werden auf DOP 1 runtergestuft). Das zeigt sich in THREADPOOL Waits – neue Abfragen hängen, bis Threads frei werden. – NUMA-Crossing: Ein sehr hoher MAXDOP überschreitet vermutlich NUMA-Knoten. Dann greifen Threads über Kreuz auf Speicher, was latenzintroduzierend ist (siehe NUMA-Abschnitt). Nicht katastrophal, aber summiert sich. – Unnötige Kontextwechsel: Jeder zusätzliche Thread bedeutet, das OS muss ihn planen. Bei sehr vielen aktiven Threads verbringt Windows mehr Zeit mit Kontext-Switching (Umschalten zwischen Threads) und weniger mit tatsächlicher Arbeit. Das kann CPU teuer werden. – Cache-Effekte: Wenn ein Plan mit 32 Threads läuft, muss das Ergebnis partitioniert und dann wieder zusammengeführt werden. Dabei werden oft Zwischenresultate sortiert und in gemeinsamen Caches gesammelt – mehr Threads = mehr Cache-Footprint = mehr Memory Traffic. Das kann ineffizient sein.

In Summe: Zu hoher MAXDOP kann die Performance verschlechtern statt verbessern – das System wirkt ausgelastet, aber einzelne Vorgänge dauern trotzdem lang. Außerdem kann es zu instabilen Situationen kommen, wenn Limits überschritten werden (Thread Mangel).

Frage 25: Was passiert, wenn MAXDOP zu niedrig eingestellt ist?
Antwort: Ein zu niedriger MAXDOP (z.B. 1 oder 2, obwohl 16 Kerne da sind und komplexe Queries anliegen) hat diese Effekte: – Lange Laufzeiten für große Abfragen: Abfragen, die eigentlich gut parallelisierbar wären (z.B. große Index-Scans, Joins über Millionen Zeilen), müssen seriell oder fast seriell laufen. Dadurch nutzen sie nicht die vorhandene Rechenpower. Sie dauern also viel länger, als nötig – was ggf. Reports verlangsamt, Ladefenster sprengt etc. – Ungenutzte CPU-Kapazitäten: Das System könnte viel mehr throughput schaffen. Stattdessen sieht man evtl., dass die CPU-Gesamtauslastung niedrig bleibt, obwohl User über langsame Abfragen klagen – weil alles brav in Einzelfäden nacheinander abgearbeitet wird. – Workload-Verzerrung: Manchmal hilft moderate Parallelität auch, Last besser zu verteilen. Wenn MAXDOP 1 global gesetzt ist, kann es z.B. passieren, dass eine einzelne Riesen-Query stundenlang einen CPU-Kern blockiert, während andere Kerne nichts tun. Mit Parallelität hätte sie vielleicht 4 Kerne für 15 Minuten genutzt und wäre fertig, was im Mittel effizienter wäre. – Verzicht auf Optimierungen: Einige Ausführungsplan-Optimierungen gibt es nur in parallelen Plänen (z.B. bestimmte Bitmap-Filter bei Joins, die nur im Parallel-Plan entstehen). Bei MAXDOP 1 gehen solche Optimierungen verloren. Das heißt, manche Abfragen könnten sogar mehr CPU verbrauchen seriell, als sie es parallel würden, weil der Plan nicht die gleichen Techniken anwendet. – Skalierungsprobleme bei vielen Nutzern: Mit MAXDOP 1 kann zwar jeder Query nur einen Thread nehmen, was dem Nebenläufigkeitsgedanken entspricht – jedoch, wenn ein paar große Abfragen laufen, bekommen alle anderen nichts von deren ungenutzten Kernen ab. Es skaliert also nicht nach oben – mehr Nutzer können die freien Ressourcen nicht automatisch nutzen, weil sie an die sequenziellen Ausführungen gebunden sind. – Spezialfall Wartezeiten: Zu niedriger MAXDOP kann sich in Wait Stats u.U. in vielen SOS_SCHEDULER_YIELD Waits äußern, weil die wenigen laufenden Threads um die CPU-Zeit rotieren, obwohl anderswo Kerne frei wären. Auch hohe LATCH_Waits oder IO-Waits könnten verstärkt auftreten, einfach weil Abfragen länger laufen und so länger Transaktionen offen halten etc.

Kurz: Der Server nutzt nicht sein Potenzial, was zu ineffizienter Hardwareauslastung und verlängerten Antwortzeiten führt. Man „drosselt“ gewissermaßen die Maschine. Für kleine OLTP-Transaktionen merkt man das evtl. nicht, aber für alles größere vermisst man die Power. Darum gilt es, MAXDOP so niedrig wie nötig, aber so hoch wie sinnvoll einzustellen.

Diese umfangreichen Erläuterungen und Empfehlungen sollen Ihnen als DBA helfen, die häufigsten Fehlerquellen bei NUMA, MAXDOP und verwandten Konfigurationen zu vermeiden. Indem Sie die Mythen kritisch hinterfragen und Best Practices befolgen, können Sie die Performance und Stabilität Ihres Microsoft SQL Servers deutlich verbessern und optimal auf Ihre spezifische Umgebung zuschneiden. Viel Erfolg beim Konfigurieren und Happy Tuning!

 

Weitere Beiträge zum Thema SQL Server

 

Azure SQL für IT-Entscheider

1. Management Summary Azure SQL bezeichnet eine Familie von Microsofts Cloud-Datenbankdiensten, die SQL Server-Technologie in Azure als Service bereitstellen. Dazu gehören Azure SQL Database (ein einzeldatenbankbasierter PaaS-Dienst für moderne Anwendungen), Azure SQL...

mehr lesen

Azure SQL für Entwickler

Management Summary Azure SQL (PaaS) bietet Softwareentwicklern eine fully-managed SQL-Plattform in der Cloud – mit integrierter Hochverfügbarkeit, automatischen Backups und einfacher Skalierbarkeit. Im Vergleich zu einer selbstverwalteten SQL Server-Instanz entfallen...

mehr lesen

NUMA – Grundlagen und Anwendung in SQL Server 2022

Grundlagen von NUMA (Non-Uniform Memory Access) Was ist NUMA?  NUMA (Nicht-uniformer Speicherzugriff) ist eine Architektur für Mehrprozessorsysteme, bei der jeder Prozessor über einen eigenen lokalen Arbeitsspeicher verfügt. Alle Prozessoren teilen sich zwar...

mehr lesen

Tutorial: SQL Server-Indizes für Entwickler

Einführung: Dieser Fachartikel richtet sich an Entwickler mit Grundkenntnissen in Microsoft SQL Server und bietet eine umfassende Einführung in das Thema Indizes. Wir beleuchten, was Indizes sind und warum sie für die Performance einer Datenbank entscheidend sind....

mehr lesen

Wartungspläne für Microsoft SQL Server

Management Summary Wartung sichert Verfügbarkeit und Datenintegrität: Geplante Wartungsarbeiten in SQL Server zielen darauf ab, die Verfügbarkeit von Datenbanken hoch zu halten und Datenintegrität zu gewährleisten. Sie minimieren Ausfallzeiten und Risiken und...

mehr lesen

Virtualisierung von SQL Server, Best Practices

Management Summary Virtualisierung von Microsoft SQL Server ermöglicht es Unternehmen, Datenbank-Workloads effizienter bereitzustellen und zu verwalten. Durch Konsolidierung mehrerer SQL-Server-Instanzen auf weniger Hardware steigern Organisationen die Auslastung und...

mehr lesen

SQL Performance-Analyse (hypothetisches Beispiel)

Management Summary Die Performance-Analyse einer Microsoft SQL-Server-Instanz (Version 2019) hat CPU- und I/O-Engpässe als Hauptprobleme identifiziert. In Spitzenzeiten lag die CPU-Auslastung dauerhaft über 90 %, und die Speicher-I/O-Latenz der Datenbanken überschritt...

mehr lesen

Weitere Beiträge zum Thema

Azure SQL für IT-Entscheider

1. Management Summary Azure SQL bezeichnet eine Familie von Microsofts Cloud-Datenbankdiensten, die SQL Server-Technologie in Azure als Service bereitstellen. Dazu gehören Azure SQL Database (ein einzeldatenbankbasierter PaaS-Dienst für moderne Anwendungen), Azure SQL...

mehr lesen

Azure SQL für Entwickler

Management Summary Azure SQL (PaaS) bietet Softwareentwicklern eine fully-managed SQL-Plattform in der Cloud – mit integrierter Hochverfügbarkeit, automatischen Backups und einfacher Skalierbarkeit. Im Vergleich zu einer selbstverwalteten SQL Server-Instanz entfallen...

mehr lesen

Wartungspläne für Microsoft SQL Server

Management Summary Wartung sichert Verfügbarkeit und Datenintegrität: Geplante Wartungsarbeiten in SQL Server zielen darauf ab, die Verfügbarkeit von Datenbanken hoch zu halten und Datenintegrität zu gewährleisten. Sie minimieren Ausfallzeiten und Risiken und...

mehr lesen

SQL Server Monitoring / Überwachung

Das Monitoring von SQL Server ist entscheidend, um die Leistung und Stabilität Ihrer Datenbank zu gewährleisten. Durch kontinuierliche Überwachung können potenzielle Probleme frühzeitig erkannt und behoben werden, bevor sie sich negativ auf Ihre Anwendungen auswirken....

mehr lesen

Microsoft SQL Server Lizenzierung

Die Lizenzierung von SQL Server kann komplex und kostspielig sein. Eine optimierte Lizenzierungsstrategie kann jedoch erhebliche Kosteneinsparungen und eine effizientere Nutzung der Ressourcen ermöglichen. Als erfahrener Berater werde ich die wichtigsten Schritte und...

mehr lesen

Microsoft SQL Server Kostenoptimierung

Die Verwaltung und Optimierung der Kosten einer SQL Server-Umgebung ist entscheidend für die Effizienz und Rentabilität eines Unternehmens. Als erfahrener Berater weiß ich, dass eine gut durchdachte Strategie zur Kostenoptimierung verschiedene Aspekte der SQL...

mehr lesen

SQL Server Analysis Services (SSAS)

SQL Server Analysis Services (SSAS) ist ein leistungsstarkes analytisches Datenbankmodul, das für Entscheidungsunterstützung und Geschäftsanalysen verwendet wird. Als erfahrener Berater weiß ich, dass SSAS eine Schlüsselrolle bei der Bereitstellung von...

mehr lesen

Microsoft SQL Server Sicherheit

Die Sicherheit von Microsoft SQL Server ist von entscheidender Bedeutung, um die Integrität, Vertraulichkeit und Verfügbarkeit Ihrer Daten zu gewährleisten. Als erfahrener Berater weiß ich, dass eine umfassende Sicherheitsstrategie verschiedene Ebenen und Methoden...

mehr lesen

Hochverfügbarkeit für Microsoft SQL Server

Die Gewährleistung der Hochverfügbarkeit (HA) von Microsoft SQL Server ist entscheidend für die Geschäftskontinuität und die Minimierung von Ausfallzeiten. Als erfahrener Berater weiß ich, dass eine gut durchdachte HA-Strategie verschiedene Technologien und Best...

mehr lesen

Indexoptimierung Microsoft SQL Server

Die Indexoptimierung ist ein zentraler Bestandteil der Leistungssteigerung eines SQL Servers. Als erfahrener Berater weiß ich, dass eine gut durchdachte Indexstrategie entscheidend für die Effizienz und Geschwindigkeit von Datenbankabfragen ist. In diesem Beitrag...

mehr lesen

Optimierung Microsoft SQL Server

Die Optimierung eines SQL Servers ist ein komplexer Prozess, der verschiedene Aspekte der Datenbankleistung berücksichtigt. Ich beschreibe hier die wichtigsten Schritte und Methoden zur Optimierung eines SQL Servers.: Die Optimierung eines SQL Servers ist...

mehr lesen