Führt varchar aufgrund von Datenfragmentierung zu Leistungseinbußen?

8

Wie werden Varchar-Spalten intern von einer Datenbank-Engine behandelt? Für eine als char (100) definierte Spalte weist das DBMS 100 zusammenhängende Bytes auf dem Datenträger zu. Bei einer Spalte, die als varchar (100) definiert ist, ist dies jedoch vermutlich nicht der Fall, da der gesamte Punkt von varchar nicht mehr Speicherplatz zuweist als erforderlich ist, um den tatsächlichen in der Spalte gespeicherten Datenwert zu speichern. Wenn ein Benutzer beispielsweise eine Datenbankzeile aktualisiert, die eine leere varchar (100) -Spalte enthält, auf einen Wert, der beispielsweise aus 80 Zeichen besteht, wo wird der Speicherplatz für diese 80 Zeichen zugewiesen? Es scheint, dass Varchar-Spalten zu einer beträchtlichen Fragmentierung der tatsächlichen Datenbankzeilen führen müssen, zumindest in Szenarien, in denen Spaltenwerte ursprünglich als leer oder NULL eingefügt und später mit tatsächlichen Werten aktualisiert werden. Führt diese Fragmentierung zu einer schlechteren Leistung bei Datenbankabfragen, im Gegensatz zur Verwendung von Werten vom Typ char, bei denen der Speicherplatz für die in den Zeilen gespeicherten Spalten zusammenhängend zugewiesen wird? Offensichtlich führt die Verwendung von varchar zu weniger Speicherplatz als die Verwendung von char, aber gibt es einen Leistungseinbruch bei der Optimierung der Abfrageleistung, insbesondere bei Spalten, deren Werte nach der ursprünglichen Einfügung häufig aktualisiert werden?

    
E Brown 27.10.2009, 14:23
quelle

6 Antworten

4

Die Datenstrukturen, die in einer Datenbank-Engine verwendet werden, sind weitaus komplexer als Sie es sich vorstellen! Ja, es gibt Probleme bei der Fragmentierung und Probleme, bei denen das Aktualisieren eines VARCHAR mit einem großen Wert einen Leistungseinbruch verursachen kann, aber es ist schwer zu erklären, welche Auswirkungen diese Probleme ohne ein tieferes Verständnis der beteiligten Datenstrukturen haben.

Für MS Sql-Server möchten Sie vielleicht mit dem Verständnis der Seiten - der grundlegenden Speichereinheit - beginnen (siehe Ссылка )

In Bezug auf die Auswirkungen von Fixes auf die Leistung und Variablenspeichertypen auf die Leistung müssen einige Punkte berücksichtigt werden:

  • Die Verwendung von Spalten mit variabler Länge kann die Leistung verbessern, da mehr Zeilen auf einer einzigen Seite Platz finden, was weniger Lesevorgänge bedeutet
  • Die Verwendung von Spalten mit variabler Länge erfordert spezielle Versatzwerte, und die Pflege dieser Werte erfordert einen geringen Aufwand, dieser zusätzliche Aufwand ist jedoch im Allgemeinen vernachlässigbar.
  • Eine weitere mögliche Kosten sind die Kosten für die Erhöhung der Größe einer Spalte, wenn die Seite mit dieser Zeile fast voll ist

Wie Sie sehen, ist die Situation ziemlich komplex - im Allgemeinen können Sie jedoch darauf vertrauen, dass die Datenbank-Engine ziemlich gut mit variablen Datentypen umgehen kann, und sie sollten der Datentyp der Wahl sein, wenn es eine signifikante Varianz gibt die Länge der Daten in einer Spalte.

An dieser Stelle werde ich auch das ausgezeichnete Buch "Microsoft Sql Server 2008 Internals" empfehlen, um mehr darüber zu erfahren, wie komplex solche Dinge wirklich werden!

    
Justin 27.10.2009, 14:42
quelle
7

Sie treffen eine Menge Annahmen in Ihrer Frage, die nicht unbedingt wahr sind.

Der Typ der a-Spalte in einem beliebigen DBMS sagt nichts über die Art der Speicherung dieser Daten aus, es sei denn, die Dokumentation sagt Ihnen eindeutig, wie die Daten gespeichert sind. WENN das nicht angegeben ist, wissen Sie nicht, wie es gespeichert wird und das DBMS ist frei, den Speichermechanismus von Release zu Release zu ändern.

Tatsächlich speichern einige Datenbanken CHAR-Felder intern als VARCHAR, während andere eine Entscheidung darüber treffen, wie die Spalte basierend auf der deklarierten Größe der Spalte gespeichert werden soll. Einige Datenbankspeicher VARCHAR mit den anderen Spalten, einige mit BLOB-Daten, und einige implementieren anderen Speicher, einige Datenbanken schreiben immer die gesamte Zeile, wenn eine Spalte aktualisiert wird, andere nicht. Einige Pad-VARCHARs ermöglichen eine begrenzte zukünftige Aktualisierung, ohne den Speicher zu verschieben.

Das DBMS ist dafür verantwortlich, herauszufinden, wie die Daten gespeichert und schnell und konsistent an Sie zurückgegeben werden. Es erstaunt mich immer wieder, wie viele Leute versuchen, die Datenbank auszuprobieren, meist im Voraus, um ein Performance-Problem zu erkennen.

    
Larry Lustig 27.10.2009 14:33
quelle
3

Die Antwort hängt von dem spezifischen DBMS ab. Für Oracle ist es sicherlich möglich, dass die Fragmentierung in Form von "verketteten Zeilen" endet und dies zu einer Leistungseinbuße führt. Sie können dies jedoch abmildern, indem Sie in den Tabellenblöcken einen leeren Speicherplatz vorbelegen, um aufgrund von Aktualisierungen eine Erweiterung zu ermöglichen. In CHAR-Spalten wird die Tabelle jedoch normalerweise viel größer, was sich wiederum auf die Leistung auswirkt. CHAR hat auch andere Probleme, wie zum Beispiel Leerzeichen aufgefüllte Vergleiche, die bedeuten, dass in Oracle die Verwendung des CHAR-Datentyps fast nie eine gute Idee ist.

    
Tony Andrews 27.10.2009 14:35
quelle
2

Ihre Frage ist zu allgemein, da unterschiedliche Datenbank-Engines ein unterschiedliches Verhalten aufweisen. Wenn Sie das wirklich wissen müssen, schlage ich vor, dass Sie einen Benchmark einrichten, um eine große Anzahl von Datensätzen zu schreiben und diese zu speichern. Sie würden genug Aufzeichnungen brauchen, um mindestens eine Stunde zu schreiben.

Wie Sie vorgeschlagen haben, wäre es interessant zu sehen, was passiert, wenn Sie schreiben, fügen Sie alle Datensätze mit einer leeren Zeichenfolge ("") ein und aktualisieren sie dann auf 100 Zeichen, die einigermaßen zufällig sind, nicht nur 100 Xs.

Wenn Sie dies mit SQLITE versuchen und keinen signifikanten Unterschied sehen, dann halte ich es für unwahrscheinlich, dass die größeren Datenbankserver mit der gesamten Analyse und Optimierung schlechter als SQLITE sind.

    
Michael Dillon 27.10.2009 14:37
quelle
2

Dies wird vollständig datenbankspezifisch sein.

Ich weiß, dass die Datenbank in Oracle einen bestimmten Prozentsatz jedes Blocks für zukünftige Aktualisierungen reserviert (Der PCTFREE-Parameter). Wenn PCTFREE beispielsweise auf 25% eingestellt ist, wird ein Block nur für neue Daten verwendet, bis er zu 75% voll ist. Auf diese Weise bleibt Raum, damit Reihen wachsen können. Wenn die Zeile so vergrößert wird, dass der reservierte Speicherplatz zu 25% vollständig belegt ist, enden Sie mit verketteten Zeilen und einer Leistungseinbuße. Wenn Sie feststellen, dass eine Tabelle eine große Anzahl von verketteten Zeilen enthält, können Sie PCTFREE für diese Tabelle optimieren. Wenn Sie eine Tabelle haben, die überhaupt keine Aktualisierungen haben wird, wäre ein PCTFREE von Null sinnvoll

    
Chi 27.10.2009 14:44
quelle
1

In SQL Server wird varchar (außer varchar (MAX)) im Allgemeinen zusammen mit dem Rest der Daten der Zeile gespeichert (auf der gleichen Seite, wenn die Daten der Zeile & lt; 8KB sind und im gleichen Umfang & lt; 64KB. Nur die großen Datentypen wie TEXT, NTEXT, BILD, VARHCAR (MAX), NVARHCAR (MAX), XML und VARBINARY (MAX) werden separat gespeichert.

    
Manu 27.10.2009 14:41
quelle

Tags und Links