Mittwoch, 7. Juli 2010

Indizes? Haben wir doch schon längst! Lassen Sie uns nun bitte zu den echten Tuning Methoden kommen.

Das ist häufig eine spontane Antwort, welche ich auf den Vorschlag bekomme eine Anwendung mittel Indizes zu optimieren, wenn so das Gröbste aus dem Weg ist.

Sowohl Entwickler als auch Administratoren scheint durchaus bewusst zu sein, dass Indizes und das Laufzeitverhalten einer Datenbank durchaus zusammenhängen (können). Aber ihnen scheint oft nicht die mögliche Tiefe des Themas bewusst zu sein, denn sie suchen häufig den wahren heiligen Gral der Performance Optimierung. Indizes haben sie schon, also muss es da draußen noch etwas anderes geben. Ist doch logisch, oder? :-)

Mit diesem Post möchte ich den Leser, welcher sich angesprochen fühlt, dafür sensibilisieren, dass Indizierung viel mehr zu bieten hat, als er sich für den Moment vielleichtnvorstellen kann.

Es hat sicherlich auch etwas damit zu tun, welche Rolle Indizes früher gespielt haben. Unter dbase III+ waren Indizes zum Beispiel eigentlich nichts anderes als nur zusätzliche Sortierreihenfolgen, welche auch für eine schnellere Suche genutzt werden konnten. Wer kann sich noch an FIND und SEEK erinnern? :-)

In einem modernen relationalem Datenbank System wie dem SQL Server schaust ein wenig anders aus. Daten liegen meist bereits in Form eines B-Trees vors. Was ist ein B-Tree? –> http://de.wikipedia.org/wiki/B-Baum. Und ja, es gibt wohl tatsächlich Fälle, in denen ein sogenannter Stapel (Heap) Sinn machen würde. Sind aber recht selten und legen wir gedanklich mal zur Seite.

Es gibt pro Tabelle daher einen gruppierten (clustered index, CI), der entspricht auch gleichzeitigt DEN DATEN, und meist eine ganze Reihe von nicht gruppierten Indizes (non-clustered index, NCI). Damit scheint das Thema bereits durch zu sein. Es werden die Spalten mit einem Index hinterlegt, nach denen später “gesucht” werden soll. Damit ist meist die Verwendung mittels WHERE gemeint. Alles Mögliche wurde getan. Dabei fängt der Spaß doch jetzt erst richtig an!

Ein Index ist nicht nur ein Weg um Daten schneller zu finden, häufig ist der Index gleichzusetzen mit den Daten. Nun ja, oder zumindest einem Teil der Daten. Am Besten den Teil der Daten, den ich gerade benötige. Ich hatte ja in einem Post darauf hingewiesen, dass die Vermeidung von IO Operationen das Ziel sein sollte. Mir bringen die schönsten Indizes nichts, wenn sich der SQL Server durch Unmengen Datenbankseiten wühlen muss.

Worauf kann geachtet werden? Und, nein, ich möchte hier keine Kurzanleitung für die effektive Indizierung liefern, sondern nur mal kurz anreißen wie weit das Thema gehen kann. by the way, viel Sinnvolles über Indizierung steht in der SQL Server Hilfe (BooksOnline)!

Fangen wir mal mit was Einfachem an. Die Wahl des richtigen Clustered Index Keys ist bereits entscheidend. Viele schauen dann auf und fragen: Welche Wahl? Ist das nicht immer der Primäre Schlüssel? Ja, per default ist er das meist, aber das muss nicht so sein und macht auch oft keinen Sinn! Denn die Reihenfolge in welcher meine Daten vorliegen ist gerade bei sogenannten Bereichsabfragen von Vorteil, aber wer fragt schon ständig von Kundennummer 4711 bis 5289 ab? Eher kommt wohl sowas vor wie “Alle Kunden in Köln” oder “Alle Umsätze in 2009”. Also ist hier die erste Chance zum Mitmachen.

Kommen wir mal zu den nicht-gruppierten Indizes. Das ist doch “nur” ein Verweis auf die Daten im gruppierten Index, oder? Ja, aber das muss nicht so sein! Weil wenn der SQL Server im NCI alles findet, was er für die Beantwortung einer Abfrage benötigt, dann ist der so clever und lässt den CI doch tatsächlich links liegen und bedient sich aus dem NCI. Nun kommt natürlich sofort die Frage: “Aber was soll eine Abfrage in der nur Ort vorkommt, weil mehr steht doch nicht im Index?!? Ich brauche doch auch noch den Umsatz!” Und da fängt der Zauber an, denn es hält uns nichts davon ab, dass wir den Umsatz einfach mit in den Index legen. Ab SQL Server 2005 gibt es für sogenannte abdeckende Indizes sogar ein extra GUI Erlebnis (Eingeschlossene Spalten). Wir erzeugen bewusst Redundanz. Das ist immer ein Moment, da zeigt sich, ob der Berater den starrenden Augen des Kunden gewachsen ist. “Was, bewusst Redundanz herbeiführen? So ein Blödsinn! Und wie wird das gepflegt?” Das Schöne ist, dass sich das selbst pflegt. Ok, die Pflege kostet extra Zeit beim Schreiben, aber wenn der lesende Zugriff unterstützt werden soll, dann macht sowas durchaus Sinn. Die meisten Anwendungen sind eh viel mehr am Lesen als am Schreiben. Passt schon, aber besser vorher mal prüfen und nicht übertreiben.

Die Reihenfolge der Spalten in einem Index spielt auch noch eine entscheidende Rolle! Hier kommt das Thema Selektivität zum tragen.

Dann kann doch tatsächlich ein View wiederum in Form eines gruppierten Index persistiert werden. Damit lässt sich häufig auch eine Menge machen. Und natürlich lassen sich auf diesem CI auch wieder NCIs anlegen.

NCI können gefiltert werden, es  wird nur ein Teil der Zeilen im CI vorgehalten. Spart wiederum Zeit bei der Pflege und Platz!

Und pro Partition können auch wieder unterschiedliche Indizes verwendet werden. Viele Indizes nur für die aktuellen Daten und für das historische Zeug nur das nötigste.

Um wem das noch nicht reicht, dem der Hinweis, dass selbst die Wahl auf welchen Festplatten welche Indizes liegen, oft zur Performance des Systems beitragen kann.

Und so weiter… wir wollten das ja auch nur mal kurz anreißen!

Das Thema Performance Tuning kann äußerst tief in die Interna des SQL Servers gehen. Häufig kommt die Frage nach dem “richtigen” Tuning. Die ist man mal meist gar nicht so einfach zu beantworten. Wie viel Tuning darf es denn sein? Am Anfang eines Performance Tuning Projektes kann meist mit einfachen Mitteln eine ganze Menge Performance rausgeholt werden. Dann geht es in die Detailanalyse, um den vielen kleinen aber lästigen Abfragen auf die Spur zu kommen. Pflicht ist dann noch ein Blick auf die Auswirkungen von parallelen Transaktionen, damit kann der Berater auch noch viel Spaß haben.

Performance Tuning ist immer ein laufender Prozess, kein einmaliges Projekt! Um trotzdem allen Maßnahmen, Möglichkeiten und Abhängigkeiten Herr zu werden empfehle ich die Verwendung eines Reifegradmodells, in welchem festgelegt wird wie viel Zeit für welches Thema wann aufgebracht werden soll. Sonst kann das Ganze leider ziemlich schnell ins Endlose ausufern und keine messbaren Erfolge bringen.

Der Lernprozess beim Performance Tuning ist wohl nie vorbei, da es immer noch eine tiefere Ebene gibt im SQL Server. Damit man aber mit seinem SQL Server überhaupt vom Fleck kommt, sollte ganz ordentlich beim Fundament angefangen werden und dann darf es nach und nach komplizierter werden. Viel es sein muss, nun ja, da empfehle ich von Koch “Die 80/20 Regel” Basiswerk zu.