SQL Server Resource Governor im Detail
Workload-Steuerung mit Resource Pools, Workload Groups und Classifier FunctionDer Resource Governor im SQL Server: Ressourcenfresser an die Leine
Wie Sie mit Resource Pools, Workload Groups und einer Classifier Function dafür sorgen, dass der Monatsexport nicht die Produktion lahmlegt
Jede produktive SQL-Server-Instanz kennt das Phänomen des lauten Nachbarn: Alles läuft rund, bis jemand den großen Export anwirft, das Controlling seine Excel-Abfrage von der Kette lässt oder ein Wartungsjob zur Unzeit startet. Plötzlich stehen die Anwender der eigentlichen Fachanwendung im Stau — und der Admin darf erklären, warum die Warenwirtschaft „mal wieder langsam" ist. Der Resource Governor ist die Antwort des SQL Servers auf genau dieses Problem: Er verteilt CPU, Arbeitsspeicher und I/O kontrolliert auf konkurrierende Workloads, statt alle in denselben Topf greifen zu lassen. In diesem Artikel schauen wir uns an, wie das Feature aufgebaut ist, wo die Fallstricke liegen und wie zwei reale Projekte damit ihre Performance-Probleme gelöst haben.
|
FAKTENKASTEN — SQL Server Resource Governor Der Resource Governor ist seit SQL Server 2008 Bestandteil des Produkts und steuert die Verteilung von CPU, Arbeitsspeicher und physischem I/O zwischen Workloads einer Instanz. Das Feature erfordert die Enterprise Edition (bzw. Developer/Evaluation Edition); in der Standard Edition und in Express ist es nicht verfügbar. Die drei Kernkomponenten sind Resource Pools, Workload Groups und die Classifier Function (eine skalare benutzerdefinierte Funktion in der master-Datenbank). CAP_CPU_PERCENT (hartes CPU-Limit) ist seit SQL Server 2012 verfügbar, die I/O-Steuerung über MIN_IOPS_PER_VOLUME/MAX_IOPS_PER_VOLUME seit SQL Server 2014. Konfigurationsänderungen werden erst mit ALTER RESOURCE GOVERNOR RECONFIGURE wirksam; die Klassifizierung erfolgt einmalig beim Verbindungsaufbau. Stand: August 2026 · boddenberg.de |
|---|
1. Wozu das Ganze? Das Problem der lauten Nachbarn
SQL Server ist von Haus aus ein Gleichmacher: Jede Session, die sich verbindet, darf sich grundsätzlich an denselben Ressourcen bedienen. Das ist fair — aber fair ist nicht immer klug. Die 200 Sachbearbeiter, die im ERP Aufträge buchen, sind für das Unternehmen schlicht wichtiger als der eine Export-Job, der einmal im Monat drei Stunden lang Daten für ein Drittsystem herausschaufelt. Ohne Steuerung gewinnt aber gern der Export: Er liest riesige Datenmengen, zieht sich fette Memory Grants, parallelisiert auf allen Kernen — und die Sachbearbeiter warten.
Die klassischen Auswege sind alle unbefriedigend: Den Export nachts laufen zu lassen scheitert oft an fachlichen Vorgaben oder an Zeitzonen. Eine zweite Instanz oder ein Reporting-Replikat kostet Lizenzen und Betriebsaufwand. Und dem Fachbereich zu erklären, er möge doch bitte „rücksichtsvoller abfragen", hat noch nie funktioniert. Der Resource Governor setzt eine Ebene tiefer an: Er lässt alle weiterarbeiten, teilt aber die Ressourcen nach Prioritäten zu. Der Export läuft weiter — nur eben gedrosselt, sodass die Anwendung nichts mehr davon merkt.
2. Die Architektur: drei Bausteine, klare Rollen
Das Konzept ist erfreulich übersichtlich. Es gibt genau drei Bausteine, und wenn Sie deren Rollen einmal verstanden haben, ist der Rest Handwerk.

Skizze 1: Eingehende Sessions werden von der Classifier Function auf Workload Groups verteilt, die wiederum an Resource Pools hängen
|
Baustein |
Aufgabe |
Typische Einstellungen |
|---|---|---|
|
Resource Pool |
Der eigentliche Ressourcentopf: partitioniert CPU, Arbeitsspeicher und physisches I/O der Instanz. |
MIN_CPU_PERCENT, MAX_CPU_PERCENT, CAP_CPU_PERCENT, MAX_MEMORY_PERCENT, MAX_IOPS_PER_VOLUME |
|
Workload Group |
Logischer Container für Sessions; hängt an genau einem Pool und regelt Verhalten auf Request-Ebene. |
IMPORTANCE, MAX_DOP, REQUEST_MAX_MEMORY_GRANT_PERCENT, REQUEST_MEMORY_GRANT_TIMEOUT_SEC, GROUP_MAX_REQUESTS |
|
Classifier Function |
Der Türsteher: entscheidet bei jedem Login, in welche Workload Group die Session wandert. |
Skalare UDF in master, ausgewertet werden z. B. SUSER_SNAME(), APP_NAME(), HOST_NAME(), IS_MEMBER() |
Zwei Pools und zwei Groups existieren immer, ob Sie wollen oder nicht: internal ist für den SQL Server selbst reserviert — Lazy Writer, Checkpoints, interne Prozesse — und lässt sich weder begrenzen noch löschen. Das ist auch gut so, denn ein SQL Server, der sich selbst aushungert, hilft niemandem. default fängt alles auf, was die Classifier Function nicht ausdrücklich woanders hinschickt. Eigene Pools und Groups legen Sie zusätzlich an; bis zu 64 Resource Pools sind seit SQL Server 2012 möglich — in der Praxis kommen Sie mit drei bis fünf gut hin, und mehr als das sollte man sich auch gut überlegen.
|
MERKE Weniger ist mehr: Jeder zusätzliche Pool mit MIN-Garantien reserviert Ressourcen, die anderen fehlen. Ein sauberes Design hat einen Pool für die geschützte Kernanwendung, einen für die Übeltäter — und den default für den Rest. |
|---|
3. Was beim Login passiert
Die Klassifizierung ist ein einmaliger Vorgang beim Verbindungsaufbau. Nach der Authentifizierung ruft der SQL Server die hinterlegte Classifier Function auf; deren Rückgabewert — der Name einer Workload Group — bestimmt, wo die Session für ihre gesamte Lebensdauer einsortiert wird. Gibt die Funktion NULL oder einen unbekannten Namen zurück, landet die Session in der default-Group.

Skizze 2: Der Weg einer Session vom Login bis zur wirksamen Ressourcenbegrenzung
|
WARNBOX — Die Classifier Function ist Ihr Login-Nadelöhr Die Funktion läuft bei jedem einzelnen Verbindungsaufbau — bei Connection-Pooling-Anwendungen also seltener, bei allem anderen ständig. Wer hier Tabellenzugriffe, Abfragen auf Konfigurationstabellen oder aufwendige Logik einbaut, verwandelt den Türsteher in einen Flaschenhals: Jeder Login wartet, bis die Funktion fertig ist. Die Regel lautet: nur In-Memory-Funktionen wie SUSER_SNAME(), APP_NAME() oder IS_MEMBER(), simple Vergleiche, WITH SCHEMABINDING, fertig. Wenn Sie Lookup-Tabellen brauchen, gehören die als hartkodierte Logik in die Funktion oder in eine memory-optimized Table — nicht als klassischer Tabellenzugriff auf eine Benutzerdatenbank. |
|---|
Wichtig für die Betriebspraxis: Eine bestehende Session wird nie nachträglich umklassifiziert. Ändern Sie die Konfiguration, gilt sie nur für neue Verbindungen. Bei Anwendungen mit Connection Pooling kann das bedeuten, dass alte Zuordnungen noch stundenlang weiterleben, bis der Pool seine Verbindungen erneuert — im Zweifel hilft ein kontrollierter Neustart des Anwendungsdienstes.
4. CPU, Memory, I/O: Was sich wie begrenzen lässt
Die Stellschrauben verteilen sich auf zwei Ebenen: Pool-Einstellungen begrenzen die physischen Ressourcen, Group-Einstellungen das Verhalten einzelner Requests. Die wichtigsten Parameter im Überblick:
|
Parameter |
Ebene |
Wirkung |
Seit |
|---|---|---|---|
|
MIN_CPU_PERCENT |
Pool |
Garantierter CPU-Anteil bei Konkurrenz — die Untergrenze, die niemand wegnehmen kann. |
2008 |
|
MAX_CPU_PERCENT |
Pool |
Weiches CPU-Limit: greift nur bei Konkurrenz. Ist sonst nichts los, darf der Pool mehr nehmen. |
2008 |
|
CAP_CPU_PERCENT |
Pool |
Hartes CPU-Limit: gilt immer, auch wenn die Instanz ansonsten Däumchen dreht. |
2012 |
|
MAX_MEMORY_PERCENT |
Pool |
Deckelt den Query-Arbeitsspeicher (Memory Grants) des Pools — nicht den Buffer Pool! |
2008 |
|
MIN_IOPS_PER_VOLUME / MAX_IOPS_PER_VOLUME |
Pool |
Begrenzung des physischen I/O je Volume — der Klassiker gegen Storage-fressende Exporte. |
2014 |
|
IMPORTANCE |
Group |
Relative Gewichtung (LOW/MEDIUM/HIGH) bei der CPU-Zuteilung innerhalb desselben Pools. |
2008 |
|
MAX_DOP |
Group |
Maximaler Parallelitätsgrad für Requests der Group — übersteuert die Serverkonfiguration. |
2008 |
|
REQUEST_MAX_MEMORY_GRANT_PERCENT |
Group |
Wie viel vom Pool-Speicher darf ein einzelner Request als Grant bekommen. |
2008 |
|
GROUP_MAX_REQUESTS |
Group |
Wie viele Requests der Group gleichzeitig laufen dürfen — der Rest wartet. |
2008 |
Der mit Abstand am häufigsten missverstandene Punkt ist der Unterschied zwischen MAX_CPU_PERCENT und CAP_CPU_PERCENT. MAX ist ein Schönwetter-Limit: Es greift nur, wenn tatsächlich mehrere Pools um CPU konkurrieren. Nachts um drei, wenn sonst nichts läuft, darf der Export-Pool trotz MAX = 25 fröhlich 90 % CPU ziehen — was oft sogar erwünscht ist, denn dann ist er schneller fertig. Wer dagegen garantierte, jederzeit vorhersagbare Obergrenzen braucht (etwa für interne Verrechnung oder um Messwerte stabil zu halten), nimmt CAP.

Skizze 3: MAX_CPU_PERCENT drosselt nur bei Konkurrenz — CAP_CPU_PERCENT deckelt immer
|
WARNBOX — Der Memory-Irrtum MAX_MEMORY_PERCENT begrenzt nicht den Buffer Pool, sondern ausschließlich den Arbeitsspeicher für Query-Verarbeitung — also Memory Grants für Sorts, Hash Joins und Co. Wer glaubt, er könne damit verhindern, dass ein Export den Datencache der Anwendung verdrängt, wird enttäuscht: Gegen Buffer-Pool-Verdrängung durch große Scans hilft der Resource Governor nicht. Was dagegen sehr wohl funktioniert: REQUEST_MAX_MEMORY_GRANT_PERCENT auf Group-Ebene verhindert, dass eine einzelne Monster-Query den Grant-Speicher leerräumt und alle anderen in RESOURCE_SEMAPHORE-Wartezustände zwingt. Das ist in der Praxis einer der wirksamsten Hebel überhaupt. |
|---|
5. Konfiguration Schritt für Schritt
Die komplette Einrichtung für ein typisches Szenario — ein gedeckelter Pool für Export-Prozesse — sieht so aus:
|
USE master; GO — 1) Resource Pool: die physischen Grenzen CREATE RESOURCE POOL Pool_Exporte WITH ( MAX_CPU_PERCENT = 25, CAP_CPU_PERCENT = 40, MAX_MEMORY_PERCENT = 30, MAX_IOPS_PER_VOLUME = 500 ); GO — 2) Workload Group: das Verhalten der Requests CREATE WORKLOAD GROUP WG_Exporte WITH ( IMPORTANCE = LOW, MAX_DOP = 2, REQUEST_MAX_MEMORY_GRANT_PERCENT = 20 ) USING Pool_Exporte; GO — 3) Classifier Function: der Tuersteher CREATE FUNCTION dbo.fn_RG_Classifier() RETURNS sysname WITH SCHEMABINDING AS BEGIN DECLARE @wg sysname = N'default'; IF SUSER_SNAME() = N'DOMAIN\svc_export' SET @wg = N'WG_Exporte'; RETURN @wg; END; GO — 4) Funktion registrieren und scharf schalten ALTER RESOURCE GOVERNOR WITH (CLASSIFIER_FUNCTION = dbo.fn_RG_Classifier); ALTER RESOURCE GOVERNOR RECONFIGURE; GO |
|---|
|
MERKE Ohne ALTER RESOURCE GOVERNOR RECONFIGURE passiert exakt gar nichts — die Konfiguration liegt dann zwar in den Metadaten, ist aber nicht aktiv. Das ist der häufigste „Warum wirkt das nicht?"-Moment überhaupt. Ob die Laufzeitkonfiguration aktuell ist, verrät die Spalte is_reconfiguration_pending in sys.dm_resource_governor_configuration. |
|---|
Vor dem Scharfschalten sollten Sie die Klassifizierungslogik testen — und zwar so, dass Sie sich nicht selbst aussperren. Bewährt hat sich ein zweistufiges Vorgehen: Die Funktion zunächst so bauen, dass sie ausschließlich einen einzelnen Test-Login klassifiziert und für alles andere default zurückgibt. Dann mit diesem Test-Login verbinden und die Zuordnung prüfen:
|
SELECT s.session_id, s.login_name, s.program_name, wg.name AS workload_group, rp.name AS resource_pool FROM sys.dm_exec_sessions s JOIN sys.dm_resource_governor_workload_groups wg ON s.group_id = wg.group_id JOIN sys.dm_resource_governor_resource_pools rp ON wg.pool_id = rp.pool_id WHERE s.is_user_process = 1; |
|---|
|
PRAXISBOX — Der Rettungsanker heißt DAC Sollte die Classifier Function jemals so danebengehen, dass reguläre Logins hängen oder falsch einsortiert werden: Die Dedicated Admin Connection (DAC) wird grundsätzlich nicht klassifiziert und läuft immer in der internal-Group. Per sqlcmd -A kommen Sie also garantiert auf die Instanz und können mit ALTER RESOURCE GOVERNOR WITH (CLASSIFIER_FUNCTION = NULL) plus RECONFIGURE den Türsteher feuern. Diesen Befehl sollten Sie griffbereit haben, bevor Sie das erste Mal scharf schalten — nicht erst googeln, wenn es brennt. |
|---|
6. Praxisbeispiel 1: Der Monatsexport und die HA-Falle
Ein Logistikunternehmen, zwei SQL-Server-Knoten in einer Availability Group, darauf die zentrale Fachanwendung mit einigen hundert gleichzeitigen Benutzern. Das Problem: An den ersten Werktagen jedes Monats laufen große Datenexporte für nachgelagerte Systeme — angestoßen von benannten Service-Accounts des Datenmanagement-Teams. In diesen Zeitfenstern brachen die Antwortzeiten der Anwendung regelmäßig ein; die Exporte lasen riesige Datenmengen, parallelisierten auf allen Kernen und dominierten das Storage.
Die Lösung war ein Lehrbuchfall für den Resource Governor: ein Pool Pool_Exporte mit CAP_CPU_PERCENT = 40 und MAX_IOPS_PER_VOLUME, dazu eine Workload Group mit IMPORTANCE = LOW und MAX_DOP = 2. Klassifiziert wurde über die Login-Namen der Export-Accounts — sauber, eindeutig, nicht manipulierbar. Ergebnis: Die Exporte dauerten statt gut zwei Stunden etwa dreieinhalb, was fachlich völlig egal war. Die Anwendung lief durchgehend stabil, die Beschwerden zum Monatsanfang verschwanden.
Die eigentliche Lektion kam beim ersten Failover-Test: Auf dem zweiten Knoten waren die Exporte plötzlich wieder ungebremst unterwegs. Der Grund ist so simpel wie fies — die gesamte Resource-Governor-Konfiguration inklusive Classifier Function lebt in der master-Datenbank, und die repliziert eine Availability Group nicht mit. Wer nur auf dem primären Knoten konfiguriert, hat nach dem Failover exakt gar nichts.
|
WARNBOX — Availability Groups: master reist nicht mit Resource Pools, Workload Groups und die Classifier Function sind Instanzkonfiguration in master. In HA-Umgebungen (Availability Groups wie klassisches Log Shipping) muss die Konfiguration auf jedem Replikat identisch gepflegt werden — per Deployment-Skript, nicht per Hand. Gehört zwingend dazu: ein Monitoring-Check, der die Konfiguration beider Knoten vergleicht. Bei dem beschriebenen Kunden läuft seitdem ein täglicher Abgleich der Pool- und Group-Definitionen über beide Replikate — Abweichung erzeugt ein Ticket. Klingt paranoid, hat aber seither zweimal einen vergessenen Knoten nach Konfigurationsänderungen gefangen. |
|---|
7. Praxisbeispiel 2: Controlling-Excel gegen die Warenwirtschaft
Zweiter Fall, anderes Kaliber: ein mittelständisches Handelsunternehmen, Warenwirtschaft auf einer SQL-Server-Instanz, und jeden Tag gegen Mittag wurde das System zäh. Die Analyse zeigte ein klassisches Muster — aus dem Controlling kamen Power-Query- und Excel-Abfragen direkt auf die Produktionsdatenbank, mit gigantischen Memory Grants und voller Parallelisierung. Eine einzige dieser Abfragen reservierte zeitweise mehr Query-Speicher als die gesamte Warenwirtschaft zusammen; andere Requests warteten im RESOURCE_SEMAPHORE.
Erster Wurf der Klassifizierung: über APP_NAME(), denn die Office-Datenverbindungen melden sich mit erkennbaren Programmnamen an. Funktionierte auf Anhieb — hat aber einen Haken, der im Review zu Recht auf den Tisch kam: Der Application Name ist ein Feld im Connection String, das jeder Client frei setzen kann. Wer sich als Warenwirtschaft ausgibt, umgeht die Bremse. Für ein Komfort-Feature ist das akzeptabel, als belastbare Grenze nicht. Die finale Classifier Function kombinierte deshalb beides: Mitgliedschaft in einer eigens angelegten AD-Gruppe der Controlling-Benutzer (geprüft per IS_MEMBER()) als primäres Kriterium, APP_NAME() nur noch als Zusatzindiz.
Die Limits selbst waren bewusst milde: REQUEST_MAX_MEMORY_GRANT_PERCENT = 15, MAX_DOP = 2, kein CPU-Cap. Der Effekt war trotzdem durchschlagend, weil das eigentliche Problem nie die CPU war, sondern die Memory Grants. Die Warenwirtschaft lief ab dem ersten Tag stabil; im Controlling dauerte die größte Auswertung statt fünf nun acht Minuten — was dort schlicht niemandem auffiel. Der schönste Satz aus dem Abschlussgespräch: „Wir dachten, ihr hättet neue Hardware eingebaut."
|
PRAXISBOX — Weniger drosseln, gezielter drosseln In beiden Projekten war der wirksamste Hebel nicht das CPU-Limit, sondern Memory Grant und MAX_DOP auf Group-Ebene. CPU-Deckel sind das, woran alle zuerst denken — Grant-Begrenzung ist das, was die Blockaden tatsächlich löst. Erst messen (Wait Stats!), dann deckeln: Wer RESOURCE_SEMAPHORE-Waits sieht, hat ein Grant-Problem, kein CPU-Problem. |
|---|
8. Betrieb und Monitoring
Ein Resource Governor ohne Monitoring ist ein Blindflug — Sie wollen wissen, ob die Limits greifen, ob Pools am Anschlag laufen und ob die Klassifizierung das tut, was sie soll. Die wichtigsten Anlaufstellen:
|
Sicht / Werkzeug |
Was Sie dort sehen |
|---|---|
|
sys.dm_resource_governor_resource_pools |
Laufzeitstatistiken je Pool: CPU-Verbrauch, Speichernutzung, I/O — die zentrale Betriebssicht. |
|
sys.dm_resource_governor_workload_groups |
Statistiken je Group: aktive Requests, Queued Requests, durchschnittliche CPU-Zeit, Grant-Timeouts. |
|
sys.dm_exec_sessions (Spalte group_id) |
Welche Session in welcher Group gelandet ist — der Klassifizierungs-Check. |
|
sys.dm_resource_governor_configuration |
Aktive Classifier Function und ob eine Rekonfiguration aussteht (is_reconfiguration_pending). |
|
Perfmon: SQLServer:Resource Pool Stats / Workload Group Stats |
Zeitreihen für CPU, Memory Grants und Co. je Pool/Group — ideal für Baselines und Alarme. |
|
sys.resource_governor_resource_pools u. a. (Katalogsichten) |
Die konfigurierten Soll-Werte — Grundlage für den Konfigurationsabgleich zwischen HA-Knoten. |
|
MERKE Vor jeder Limitierung eine Baseline ziehen: mindestens eine Woche Pool-/Group-Statistiken sammeln, bevor Grenzen gesetzt werden. Limits ohne Baseline sind geraten — und geratene Limits sind entweder wirkungslos oder würgen die Falschen ab. |
|---|
9. Grenzen: Was der Resource Governor nicht kann
So nützlich das Feature ist — es lohnt sich, die Grenzen klar zu benennen, bevor falsche Erwartungen entstehen:
Richtig eingeordnet ist der Resource Governor damit kein Performance-Wundermittel, sondern ein Priorisierungswerkzeug: Er sorgt dafür, dass die wichtigen Workloads die Ressourcen bekommen, die ihnen zustehen — und dass die unwichtigen ihre Arbeit trotzdem erledigen dürfen, nur eben in der Holzklasse.
Häufig gestellte Fragen (FAQ)
Welche SQL-Server-Edition brauche ich für den Resource Governor?
Die Enterprise Edition. Developer und Evaluation Edition können das Feature ebenfalls (für Test und Entwicklung), die Standard Edition und Express dagegen nicht. Das ist in Projekten regelmäßig der erste Punkt, an dem die schöne Idee scheitert — die Editionsfrage gehört deshalb ganz an den Anfang jeder Planung.
Seit welcher Version gibt es welche Funktionen?
Das Grundgerüst — Pools, Groups, Classifier, CPU- und Memory-Steuerung — existiert seit SQL Server 2008. Mit SQL Server 2012 kamen CAP_CPU_PERCENT (hartes CPU-Limit), Affinity-Steuerung auf Pool-Ebene und die Erhöhung auf 64 Pools hinzu. SQL Server 2014 ergänzte die I/O-Steuerung über MIN_IOPS_PER_VOLUME und MAX_IOPS_PER_VOLUME. Seither ist das Feature funktional weitgehend stabil geblieben.
Funktioniert der Resource Governor in Azure?
Differenziert: In Azure SQL Database steht er nicht zur eigenen Konfiguration bereit — Microsoft nutzt ihn dort intern zur Steuerung der Service-Tiers. In Azure SQL Managed Instance können Sie ihn wie gewohnt konfigurieren. Auf SQL Servern in Azure-VMs gilt schlicht die normale Editionsregel.
Kann ich damit eine bestimmte Datenbank begrenzen?
Nicht direkt — klassifiziert werden Sessions, nicht Datenbanken. Indirekt geht es aber oft trotzdem: Wenn eine Anwendung „ihre" Datenbank über dedizierte Logins nutzt, klassifizieren Sie einfach diese Logins. Alternativ lässt sich in der Classifier Function ORIGINAL_DB_NAME() auswerten — das greift allerdings nur, wenn die Datenbank im Connection String angegeben wird, und ist entsprechend umgehbar.
Was passiert mit Sessions, die die Classifier Function nicht zuordnet?
Sie landen in der default-Group im default-Pool. Das ist ein bewusst gutmütiges Verhalten: Ein NULL-Rückgabewert, ein Tippfehler im Group-Namen oder ein Fehler in der Funktion sperren niemanden aus, sondern führen nur zur Standardzuordnung.
Wirken Konfigurationsänderungen auf bestehende Sessions?
Nein und ja. Die Klassifizierung einer Session steht mit dem Login fest und ändert sich nie mehr. Geänderte Limits eines Pools oder einer Group wirken nach dem RECONFIGURE dagegen auch auf Sessions, die dieser Group bereits zugeordnet sind — nur die Zuordnung selbst bleibt fix. Wer Sessions in eine andere Group bringen will, braucht einen Reconnect.
Ich habe mich mit der Classifier Function ausgesperrt — was nun?
Ruhe bewahren und die Dedicated Admin Connection nutzen: sqlcmd -A (oder ADMIN:Servername im SSMS-Verbindungsdialog, dort nur mit dem Abfragefenster). Die DAC wird nicht klassifiziert und funktioniert daher immer. Darüber setzen Sie ALTER RESOURCE GOVERNOR WITH (CLASSIFIER_FUNCTION = NULL); gefolgt von ALTER RESOURCE GOVERNOR RECONFIGURE; ab — damit ist der Türsteher entlassen und alle neuen Sessions laufen wieder in default.
Wie verhält sich der Resource Governor in Availability Groups?
Er weiß schlicht nichts von ihnen. Die gesamte Konfiguration liegt in der master-Datenbank und ist damit reine Instanzkonfiguration — sie wird von der Availability Group nicht repliziert. Sie müssen die Konfiguration auf jedem Replikat identisch pflegen, idealerweise skriptbasiert über eine Deployment-Pipeline, und den Gleichstand regelmäßig automatisiert prüfen. Wer das nicht tut, verliert seine Limits beim ersten Failover (siehe Praxisbeispiel 1 — das ist keine theoretische Gefahr).
Kostet der Resource Governor selbst Performance?
Der laufende Betrieb ist praktisch kostenlos — die Ressourcenzuteilung erledigt der Scheduler ohnehin, der Governor gibt ihm nur andere Regeln mit. Der einzige relevante Overhead ist die Classifier Function beim Verbindungsaufbau: Ist sie schlank gebaut, reden wir über Mikrosekunden. Ist sie es nicht, haben Sie ein selbstgemachtes Problem (siehe Warnbox in Kapitel 3).
MAX_CPU_PERCENT oder CAP_CPU_PERCENT — was soll ich nehmen?
Als Standardempfehlung: MAX. Es drosselt nur dann, wenn tatsächlich Konkurrenz herrscht, und lässt Ressourcen nicht ungenutzt brachliegen — der Export darf nachts Vollgas geben und ist schneller fertig. CAP ist das Werkzeug für Sonderfälle: garantiert vorhersagbares Verhalten, interne Leistungsverrechnung, oder wenn ein Prozess auch ohne Konkurrenz nachweislich Schaden anrichtet (etwa durch Storage-Sättigung, die andere Systeme auf demselben SAN trifft).
Was gewinnt: MAX_DOP der Workload Group oder die Serverkonfiguration?
Die Workload Group übersteuert die serverweite Einstellung für ihre Requests. Ein Query-Hint OPTION (MAXDOP n) kann innerhalb der Group wiederum abweichen — aber nur nach unten bzw. bis zum Group-Limit: Das MAX_DOP der Group wirkt als harte Obergrenze, über die auch ein Hint nicht hinauskommt. Genau dafür ist es da — es entmachtet die „ich hab mir MAXDOP 16 in die Query geschrieben"-Fraktion zuverlässig.
Kann ich die Klassifizierung über den Anwendungsnamen steuern?
Technisch ja, über APP_NAME() — aber mit einer wichtigen Einschränkung: Der Application Name ist ein frei setzbares Feld im Connection String. Jeder, der seinen Connection String ändern kann, kann sich damit in eine andere Group mogeln. Für Komfort-Szenarien („alles, was nach Excel aussieht, in den Reporting-Pool") ist das völlig in Ordnung; als belastbare Grenze taugt nur die Identität, also Login-Name oder AD-Gruppenmitgliedschaft per IS_MEMBER().
Hilft der Resource Governor gegen tempdb-Probleme?
Nur sehr indirekt. Es gibt kein tempdb-Platzkontingent pro Pool. Was Sie tun können: über REQUEST_MAX_MEMORY_GRANT_PERCENT und MAX_DOP die Abfragen zähmen, die typischerweise massive Sort-/Hash-Spills nach tempdb verursachen — das reduziert die tempdb-Last als Nebeneffekt. Für echte tempdb-Sorgen bleiben die klassischen Mittel: ausreichend Datendateien, schnelles Storage und Query-Tuning.
Ist der Resource Governor ein Ersatz für Query-Optimierung?
Nein — er ist die Ergänzung dafür. Der Resource Governor beantwortet die Frage „wer darf wie viel", nicht „warum braucht diese Abfrage so viel". Die nachhaltige Reihenfolge in jedem Projekt: erst messen, dann die schlimmsten Abfragen tunen, und den Resource Governor als Schutzschicht darüberlegen, damit die verbleibenden Ressourcenfresser die Kernanwendung nicht mehr treffen können. Wer nur deckelt und nie tunt, verwaltet seine Probleme, statt sie zu lösen.
boddenberg.de — IT-Consulting · Software Engineering · Technologieseminare. Fragen zum Resource Governor, zu SQL-Server-Performance oder HA-Architekturen? Sprechen Sie mich an.
