In den letzten Jahrzehnten wurden wir sehr häufig aufgefordert, SQL Server Umgebungen hinsichtlich evtl. vorhandener Performance bzw. Ressourcen Engpässen zu analysieren.
Die üblichen Verdächtigen sind dabei i.d.R. der verfügbare Hauptspeicher, die Anzahl der CPU Kerne, die Netzwerkanbindung als auch der Durchsatz des Storage Systems.
Sofern diese Fragestellungen zuerst im Raum stehen, dann sprechen wir gerne auch von einer infrastrukturellen Sichtweise auf den Betrieb bzw. die Performance eines SQL Servers. Ein Server wird als die Summe seiner verfügbaren Ressourcen verstanden. Diese Sichtweise ist auch zunächst einmal nicht falsch. Dahinter steht die Idee, dass ein Server mit steigender Last auch mehr Ressourcen benötigt, um diese verarbeiten zu können. Man verwendet dabei auch gern den Begriff "skalieren", um zu beschreiben, dass der Bedarf an Ressourcen (und damit meist auch Budget) und steigende Arbeitslast in Korrelation zueinander stehen.
Nun ist es aber so, dass viele relationale Datenbanksysteme sich nicht wie klassische Applikationsserver verhalten. Auf Applikationsservern läuft i.d.R. eine Form von Middleware, welche in den meisten Fällen in einer Programmiersprache entwickelt wurde. Programmiersprachen, wie z.B. Java, C#, Python, Go, Rust, werden vor ihrer Verwendung mittels eines Compilers in "etwas" Ausführbares übersetzt. Man spricht dabei gern von einer "Binary", welche dann ausgeführt wird.
Das Schöne an diesen Programmiersprachen ist, dass sich Programme immer gleich verhalten. Das mag nun wie eine offensichtliche Binsenweisheit klingen, muss aber im Kontrast zum SQL Server gesehen werden.
In der Welt der relationalen Datenbanksysteme wird meist ein von SQL abgeleiteter Dialekt verwendet. Bei dem SQL Server handelt es sich dabei um T-SQL. Alle, wirkliche alle Zugriffe auf die Datenbanken eines SQL Servers können nur mittels T-SQL erfolgen.
Was ist nun so Besonderes an T-SQL? Ist das nicht eine Programmiersprache wie jede andere auch?
Nein, ist sie nicht. Und das ist "eigentlich" auch gut so. Denn der SQL Server prüft quasi vor jeder Ausführung eines T-SQL Statements, wie er dieses optimal ausführen kann. Und dabei schaut er sich vorher um. Er liest evtl. vorhandene Parameter des T-SQL Statements aus. Er schaut sich die aktuelle physikalische Struktur der Datenbanken an, also Tabellen, Indizes usw. Des Weiteren schaut er sich die Daten in den Datenbanken an. Dabei geht es nicht nur um die Menge, sondern viel eher um eine statistische Betrachtung der Verteilung von Werten auf Spaltenebene. Dazu kommen noch 1-2 Einstellungen des SQL Servers, welche er ebenfalls berücksichtigt. Und aus diesen Informationen erstellt er einen Plan, welches quasi das SQL Server Äquivalent zur "Binary" ist und führt diese aus. Um die Sache noch ein wenig interessanter zu gestalten, merkt der SQL Server sich diesen Plan für eine gewisse Zeit, um die CPU Last für die Erstellung zu reduzieren.
Dieses Konzept klingt zunächst sehr praktisch und äußerst nützlich. Das T-SQL wird optimiert für die jeweilige Situation und Umgebung.
Auf der anderen Seite heißt das aber auch, dass die Entwickler einer Anwendung, welche T-SQL direkt oder auch nur indirekt (z.B. über ORM Tools) verwendet, eigentlich keine wirkliche Kontrolle über die Ausführung haben. Die Kontrolle über die eigentliche Ausführung wird an den SQL Server delegiert, welcher nun "versucht" das Beste aus der jeweiligen Situation zu machen.
Und hier wird es nun spannend für unsere Engpass Betrachtung bzw. für unsere Suche nach diesem.
Denn nun haben wir auf einmal die Frage im Raum, was wir eigentlich optimieren möchten oder sollen? Denn ein möglicher Ressourcenengpass zeigt uns immer nur einen Mangel auf und nicht den eigentlichen Grund dafür.
Also, wenn nun z. B. ein T-SQL Statement mit einer gegebenen physikalischen Struktur auf eine eher unerwartete Verteilung von Daten trifft, dann wird der SQL Server versuchen, das Beste draus zu machen. Im Zweifel wird er einfach deutlich mehr vorhandene Ressourcen verwenden als üblich. Mit anderen Worten: Das wird teuer!
Auf der Seite einer Engpass Betrachtung sieht man nun vielleicht eine wesentlich höhere CPU Auslastung oder einen deutlich zu knappen Hauptspeicher. Bei Beidem kann durch ein entsprechendes Budget nachgelegt werden. Zumindest in on-premises Umgebungen, in einer Cloud Umgebung ist das schon nicht mehr so einfach.
Nur ist leider nicht garantiert, dass solche Budget Pflaster lange halten werden.
Daher gehört unserer Meinung nach bei einem SQL Server Performance Audit auch immer eine Bewertung der Qualität des Workloads dazu. Also, ob die Mehrheit der T-SQL Statements wirklich sinnvollen Gebrauch von den vorhandenen Ressourcen der jeweiligen Umgebung machen. Und dabei bitte vor Augen haben, dass nur weil ein T-SQL Statement in einer Umgebung ausreichend "schnell" verarbeitet wird, es keine Garantie gibt, dass das auch in einer anderen Umgebung wieder so der Fall sein wird.
Zusammengefasst kann gesagt werden, dass identifizierte Ressourcen Engpässe meist gut auf ein Problem aufmerksam machen können. Nur die Lösung des Problems ist meist nicht das nicht hinterfragte Aufstocken dieser Ressource, sondern oft nur der Beginn der Analyse des Workloads der Umgebung und seiner Optimierung.
Natürlich gibt es immer wieder Managemententscheidungen, welche aus der Notwendigkeit heraus eine sofortige Ressourcenerweiterung nötig machen, um ein akutes Problem zumindest kurzfristig zu minimieren. Das ist völlig legitim.
Sollten Sie neugierig geworden sein bzgl. unserer Vorgehensmodelle und Systeme, dann empfehlen wir Ihnen auch u. a. folgende Artikel: