Am 14. September 2017 haben wir eine überarbeitete Fassung unserer Datenschutzrichtlinie veröffentlicht. Wenn Sie video2brain.com weiterhin nutzen, erklären Sie sich mit diesem überarbeiteten Dokument einverstanden. Bitte lesen Sie es deshalb sorgfältig durch.

SQL Server: Performance-Optimierung

Tabellendesign im Detail – Datentypen, Unicode und Big Large Objects

LinkedIn Learning kostenlos und unverbindlich testen!

Jetzt testen Alle Abonnements anzeigen
Was ist beim Design einer Tabelle zu beachten um gute Performance zu erhalten?
13:44

Transkript

Tja, die Wahl des richtigen Datentyps. Ein riesiges Kapitel eigentlich. Nichtsdestotrotz gibt es einige Kernfragen, die man sich einfach mal durch den Kopf gehen lassen sollte. Zum Beispiel: Benötige ich immer Datum und Uhrzeit, wenn ich entsprechende Informationen ablege oder reicht es nicht, das ich nur das Datum oder nur die Uhrzeit abliege? So ein Standardbeispiel ist zum Beispiel Vertragsbeginn, Vertragsende, Geburtsdatum. Da reicht mir natürlich nur das Datum. Das bedeutet, das ich natürlich nicht immer so einen Zeitanteil mitschleppen muss, der natürlich letztendlich für irgendwelche ??? umgewandelt werden muss, also nur das Datum, weil mich die Uhrzeit nicht interessiert, es wird mehr Platz benötigt und so weiter und so fort. Das ist dann so eine Frage, wo man sagen kann, OK hier wähle ich einfach den richtigen Datentyp, ich nehme einfach DATE weil ich benötige einfach schlicht und ergreifend keinen Uhrzeitanteil oder auch vice versa, wenn es um Start und Ende einer Veranstaltung geht, reicht möglicherweise schlicht und ergreifend die Uhrzeit. Dann etwas, was ich immer wieder sehe. Das lässt sich nicht so richtig ausmerzen. Ich vermute, das kommt aus anderen Bereichen der Datenverarbeitung, vielleicht vom Großrechner oder Ähnlichem, das sehr gerne für Ja/Nein Information statt einem Bit ein CHAR(1) genommen wird, wo dann so etwas wie 0 oder 1, Y oder N oder J oder N entsprechend zu finden sind, und in den ganzen Abfragen wird dann einfach auf J geprüft. Das kann ich natürlich machen aber der SQL Server kennt natürlich den Datentyp Bit, wo ich Ja/Nein also 0 oder 1 abspeichern kann, und entsprechend wenn ich mehrere Spalten vom Typ Bit haben, werden die zu einer Bitmap, quasi zu einem Byte oder Ähnlichem zusammengefasst. Das heißt, es ist schon sehr effizient, was ich da finde, und für die Verarbeitung ist es natürlich auch klarer dass ich ein Ja/Nein Feld habe und nicht etwas, wo ich einen CHAR(1) habe, wo theoretisch auch irgend etwas anderes drin stehen könnte. Insofern habe ich da natürlich zum Einen von der Datenhaltung aber auf der anderen Seite auch entsprechend von der Logik, die darauf aufbaut, sicherlich ne gute Wahl getroffen, wenn ich mich irgendwann dazu entschließe, die Daten schlicht und ergreifend als Bit, 0 oder 1, abzulegen. Der nächste Punkt, er auch sehr beliebt ist: der SQL Server kennt eine ganze Reihe von Integer Datentypen und die werden sträflich in vielen Situationen schlicht nicht benutzt. Es gibt einen TINYINT, SMALLINT und BIGINT. Das bedeutet, von einem Byte über ein Wort, was zwei Bytes sind über ein INTEGER, 4 Byte und BIGINT, 8 Bytes. Entsprechend habe ich da die Auswahl und das ist allemal eine bessere Entscheidung, in vielen Fällen, nicht immer, das zu benutzen, statt DECIMAL(n,0). Das kann ich natürlich machen, das bedeutet aber in vielen Fällen auch wieder erhöhten Verarbeitungsaufwand. und sollte eigentlich meiner Meinung nach nicht wirklich benutzt werden. Das DECIMAL(n,0) können Sie benutzen, wenn Sie technische Informationen ablegen wollen, technische Maße in irgendeiner Form, und da kann es natürlich mal sein, das ich irgendetwas habe, eine DIN Norm oder eine ISO Norm, wo möglicherweise die Angabe in Millimeter Komma Null zu finden sind. Dann würde ich wahrscheinlich auch das Decimal benutzen schlicht und ergreifend, um ein bisschen einheitlicher zu sein, um nicht möglicherweise mal hier diesen Datentyp mal da den anderen Datentyp zu haben sondern einfach zu sagen: Decimal, sagen wir mal 18,2 auch wenn es beispielsweise nur ganze Millimeter sein können, in dem speziellen Fall vielleicht keine Zehntel oder Hundertstel Millimeter. aber wenn ich dann beispielsweise in der gleichen Norm andere Angaben habe, die sehr wohl diese Nachkommastellen benötigen, dann habe ich halt einen einheitlichen Datentyp und das ist natürlich möglicherweise auch ne ganz gute Entscheidung an der Stelle. Dann Frage CHAR versus VARCHAR(1). Eigentlich sollte die Antwort relativ klar sein, weil ein CHAR ist natürlich genau ein Zeichen, das wäre eigentlich genauer gesagt auch so ein CHAR(1), wo ich genau ein CHAR ablege, einen Character ablege, statt VARCHAR, weil VARCHAR bedeutet variable Länge und das bedeutet, wenn ich einen VARCHAR(1) wiederum habe, das er zum Einen die Information abspeichern muss, welches Zeichen das ist das ist dann möglicherweise ein Byte und gleichzeitig noch die Information, wie lange diese variable Zeichenkette denn ist und das sind noch mal 2 Bytes. Es ist sicherlich relativ leicht zu erkennen, dass es möglicherweise kein effizenter Ansatz ist, wirklich ein einzelnen Zeichen abzuspeichern plus 2 weitere Bytes, Metainformationen, um die Länge abzulegen, die offensichtlich ja nur 1 sein kann. Es wäre auch 00 möglich, aber da wäre es vielleicht besser, das Feld entsprechend als NULL zu definieren. Und das sind nur einige Beispiele, die sehr prominent vorkommen. Letztendlich möchte ich Ihnen damit auf den Weg geben: wenn Sie sich Gedanken darüber machen, welche Datentypen Sie verwenden, schauen Sie, ob es nicht etwas gibt, was besser passt an der Stelle. wo der SQL Server möglicherweise effizienter mit umgehen kann. Und wählen Sie dann diesen Datentypen. Das ist auf der einen Seite für die Performance nicht unbedingt das Schlechteste, auf der anderen Seite natürlich sorgt es auch ein bisschen für Datenhygiene. Hier zum Beispiel wie gesagt im Fall des Bits und des VARCHAR, das ich da entsprechend natürlich das Richtige ablege, und damit nicht noch irgendwelche zusätzlichen Informationen in dieses CHAR Feld unterbringe. Die nächste interessante Frage, die sich oftmals beim Tabellendesign stellt, ist benutze ich Unicode oder keinen Unicode für Zeichenketten. Unicode selber ermöglicht es Ihnen, jeglichen, oder fast jeglichen Zeichensatz zu verwenden, den Sie in der IT benutzen können. Also durchaus Kyrillisch, Japanisch, Chinesisch und so weiter und so fort. Die Kosten dafür sind aber doppelter Speicherbedarf. Das sieht man schon daran, das wenn ich eine Zeichenkette mit Unicode anlegen möchte, stehen mir maximal 4000 Zeichen zur Verfügung, während es bei nicht Unicode wenigstens 8000 sind, das Doppelte. Das heißt, ich kann schon mal sagen, das Unicode mich doppelt so viel Platz kostet und doppelt so viel Arbeit für die IO Systeme. Das heißt, nur in Situationen, wo ich wirklich diese größer Auswahl an Zeichensätzen benötige, wenn meine Anwendung überhaupt so International aufgestellt ist, dann macht es Sinn, Unicode überhaupt in Erwägung zu ziehen. Es macht nicht Sinn, Unicode in Erwägung zu ziehen, wenn ich sowieso nur mit deutschen, französischen, spanischen oder ähnlichen Umlauten aus dem westeuropäischen Raum zu tun habe, weil all das kann ich noch mit ASCII abdecken und da habe ich gar nicht die Notwendigkeit, wirklich auf Unicode umzuschwenken. Auf keinen Fall brauche ich Unicode in Momenten, wo ich technische Informationen ablege, sei es eine Webseite sei es eine E-Mail Adresse, sei es ein technischer Schlüssel oder ähnliches. Das sind Informationen, die schlicht und ergreifend niemals im Falle einer E-Mail Adresse oder einer Webseite Unicode benötigen, oder in 99,99% aller Fälle sei es jetzt ein technischer Schlüssel, da weiß ich natürlich nicht, was Sie in Ihrer Anwendung haben. Aber die Wahrscheinlichkeit, dass da wirklich ein Unicode Zeichen dabei ist ist so gut wie ausgeschlossen. Und da muss man sich wirklich überlegen, möchte ich jetzt wirklich für diese Restwahrscheinlichkeit allen Zeilen in dieser Spalte diesen Mehraufwand zumuten oder nicht. Das betrifft unter anderem zum Beispiel auch das Sortieren. Das heißt, eine Sortierung nach Unicode ist viel aufwändiger als eine Sortierung nicht nach Unicode. Für Details habe ich unten mal diesen Link auf die Folie geschrieben. Und letztendlich überlegen Sie sich wirklich, brauche ich Unicode? Kann ich an der Stelle von den Vorteilen, also von der Riesenauswahl an Zeichensätzen, kann ich davon überhaupt profitieren? oder ist das schlicht und ergreifend für mich verschwendeter Datenplatz. Auch spannend ist die Frage: Soll ich eine Spalte NULLABLE machen in der Datenbank oder nicht? In vielen Fällen habe ich die Wahl, bei einigen Fällen habe ich die Wahl nicht, zum Beispiel, wenn es darum geht, PrimaryKey oder Ähnliches zu haben, dann macht es keinen Sinn, dort eine Spalte anzugeben, die NULL zulässt an der Stelle. In vielen Fällen ist es aber durchaus möglich und auch sinnvoll in vielen Fällen. Stellen Sie sich NULL als dritten Zustand vor. Das heißt, NULL bedeutet im Wesentlichen, ich weiß es nicht oder es spielt an der Stelle keine Rolle, welcher Inhalt in der Spalte vorhanden ist. Insofern kann ich damit schon mal sagen: OK Im Falle einer Namensspalte kann ich sagen die mache ich zum Beispiel NULLABLE. Weil es kann sein, dass ein Mitarbeiter, der über eine entsprechende Maske die Daten erfasst, an der Stelle schlicht und ergreifend nicht weiß, wie der Name an der Stelle aussieht. Das heißt, mit wem redet er überhaupt? Oder Vorname, das ist vielleicht wahrscheinlicher, den Nachnamen kennt man in vielen Fällen. Beim Vornamen kann es schon so sein, das ich den gar nicht kenne. Und dann macht es natürlich Sinn, diese Spalte in der Datenbank wirklich als NULLABLE zu kennzeichnen und ich kann damit natürlich sicherstellen, das ich darüber hinaus die Information habe. Ich weiß es einfach nicht. Letztendlich können Sie sich aber NULLABLE Spalten auch als leere Spalten vorstellen und da macht es auch Sinn, im SQL Server zu sagen: Pass auf die Spalte, das steht schlicht und ergreifend nichts drin. Damit habe ich die Möglichkeit, dass der SQL Server da natürlich eine effizientere Verarbeitung und Speicherung durchführen kann und ich zum Beispiel eines Strings, also VARCHAR beispielsweise nicht einen leeren String eingeben muss und wirklich sage: OK, da steht wirklich in der Tat NULL drin und letztendlich macht das auch Sinn, wie gesagt, für die Verarbeitung für die Speicherung, für die Arbeit der IO Systeme, das Sie die Spalten, die potentiell leer sein können, in der Tat auch als NULL in der einzelnen entsprechenden Zeile, wo keine Informationen vorliegen, auch als solche ablegen dann. Ein weiterer Interessanter Punkt sind so genannte BLOBS, also big large objects und der SQL Server hat solche in Form von (N) VARCHAR oder VARCHAR (MAX) TEXT oder IMAGE oder Ähnliches. Das bedeutet: Ich kann an der Stelle beliebig viele Informationen unterbringen, was praktisch bedeutet, bis zu 2 GB an Informationen. Das klingt erst mal verlockend. Aber überlegen Sie sich: Brauche ich das wirklich? Weil wenn ich beispielsweise ein Feld habe, wo ich eine kleine Beschreibung unterbringen kann oder einen Namen oder Ähnliches und ich habe in der Maske sowieso nicht genügend Platz, um dort Romane zu schreiben, macht es dann wirklich Sinn, eine solche Spalte als (N) VARCHAR oder VARCHAR (MAX) anzulegen? Ich denke in vielen Fällen schlicht und ergreifend nein. Und deshalb sollten Sie sich es auch wirklich überlegen, wenn Sie eine Datenbank kreieren, ob Sie dann diese Datentypen wirklich benutzen. Manchmal macht es durchaus Sinn. Wenn Sie beispielsweise binäre Informationen unterbringen wollen oder wirklich potentiell sehr, sehr lange Texte, und das bedeutet in dem Fall von VARCHAR schon mehr als 800 und im Fall von (N) VARCHAR mehr als 4000 Zeichen. In dem Fall haben Sie gar keine andere Wahl. Für Namen, für Adressen, für Produktbeschreibungen, für Produktnamen oder Ähnliches wird es in der Regel ausreichen, eine maximale Länge anzugeben und nicht mit diesem MAX zu arbeiten. Der MAX hat nämlich einen ganz gravierenden Nachteil in diesem Kontext, und zwar ist es dann ein Out of Row Storage. Das bedeutet, der Inhalt wird nicht wirklich an der Stelle gespeichert, sondern es ist ein Pointer, der irgendwoanders in die Datenbank rein zeigt und wen ich in dem Moment auf diese Daten zugreife, dann muss der SQL Server auch diese Seite oder Seiten laden, um die Informationen zur Verfügung zu stellen und das ist natürlich relativ aufwändig. Außerdem bedeutet das, das jeder Inhalt auch wenn er nicht NULL ist, also genau wenn er Nicht NULL ist, dann entsprechend mit 24 Bytes zur Rechnung beiträgt und das ist natürlich ein ziemlicher Ansatz, wenn ich einen kleinen kurzen Namen einfach in dieser Spalte habe, kostet mich das 24 Bytes an der Stelle. Das ist natürlich nicht so richtig schön. Und auch der SQL Server hat einen Todesstern sozusagen. Nämlich SELECT* von irgendetwas. Und der Name kommt ganz einfach daher, nicht das man von der schwarzen oder der dunklen Seite kommt, sondern weil man natürlich wenn ich SELECT* habe, potentiell den kompletten Inhalt einer solchen BLOB Spalte an den Client zurück liefert und ich kann mir vorstellen, das es Szenarien gibt, wo Sie eine Tabelle haben, die Informationen über beispielsweise eine Person speichert, dass das Bild, das einige kB, vielleicht sogar einige hundert kB groß ist, natürlich nicht immer mit dazugehört. Wenn ich einfach sag: OK, ich mach SELECT* dann werden alle Informationen dieser Zeile, dieser Person an den Client geschickt, auch wenn der möglicherweise nur Name und Vorname anzeigt. Es ist natürlich für alle anderem Spalten auch nicht besonders effizient aber im Fall eines BLOBS habe ich dann nur einige kB oder wenige kB während wie gesagt, ein Bild oder eine Bewerbung oder größere Dokumente schlicht und ergreifend sehr sehr viel Platz, Netzwerkkapazität und letztendlich einfach schlicht Ressourcen kosten, obwohl sie gar nicht benötigt werden. Das heißt, überlegen Sie sich wirklich, an welche Stellen Sie wirklich VARCHAR ,(N) VARCHAR, MAX, TEXT, IMAGE oder Ähnliches einsetzen, und gerade die ersten beiden, also (N) VARCHAR und VARCHAR (MAX) sind sehr häufig Fehler, die ich im Datenbankdesign sehe. Das liegt aber auch ein bisschen daran, dass wenn Sie beispielsweise vom Entity Framework sich die Datenbank aufsetzen lassen, das er, sofern Sie keine detaillierten Angaben machen, die Text, die String Spalten immer als (N) VARCHAR (MAX) anlegt, und damit macht er wahrscheinlich direkt an zwei verschiedenen Stellen was falsch. Nämlich brauche ich wirklich Unicode, siehe oben, und muss es wirklich MAX sein? Aber das ist recht technisch bedingt und da kann ich natürlich dann im Desing des Entity Framework Models durchaus nachbessern und ein bisschen feinschleifen.

SQL Server: Performance-Optimierung

Lernen Sie den Umgang mit Indizis und Tools, um die Leistungsfähigkiet Ihrer SQL Server Datenbank effektiv zu erhöhen.

3 Std. 20 min (32 Videos)
Derzeit sind keine Feedbacks vorhanden...
 
Hersteller:
Software:
Exklusiv für Abo-Kunden
Erscheinungsdatum:04.05.2017

Dieser Online-Kurs ist als Download und als Streaming-Video verfügbar. Die gute Nachricht: Sie müssen sich nicht entscheiden - sobald Sie das Training erwerben, erhalten Sie Zugang zu beiden Optionen!

Der Download ermöglicht Ihnen die Offline-Nutzung des Trainings und bietet die Vorteile einer benutzerfreundlichen Abspielumgebung. Wenn Sie an verschiedenen Computern arbeiten, oder nicht den ganzen Kurs auf einmal herunterladen möchten, loggen Sie sich auf dieser Seite ein, um alle Videos des Trainings als Streaming-Video anzusehen.

Wir hoffen, dass Sie viel Freude und Erfolg mit diesem Video-Training haben werden. Falls Sie irgendwelche Fragen haben, zögern Sie nicht uns zu kontaktieren!