Soll ich varchar(255)
oder varchar(256)
beim Entwerfen von Tabellen verwenden? Ich habe gehört, dass ein Byte für die Länge der Spalte oder zum Speichern von Metadaten verwendet wird.
Ist es jetzt noch wichtig?
Ich habe einige Posts im Internet gesehen, die jedoch für Oracle und MySQL gelten.
Wir haben Microsoft SQL Server 2016 Enterprise Edition. Wie trifft dies auf diese Umgebung zu?
Sagen Sie jetzt zum Beispiel, was ist, wenn ich meinen Kunden gesagt habe, dass sie zum Beispiel eine Textbeschreibung mit 255 Zeichen anstelle von 256 beibehalten sollen? Gibt es einen Unterschied? Was ich gelesen habe "Mit einer maximalen Länge von 255 Zeichen kann das DBMS ein einzelnes Byte verwenden, um die Länge der Daten in dem Feld anzugeben. Wenn das Limit 256 oder mehr wäre, wären zwei Bytes erforderlich." Ist das wahr?
Antworten:
Größe jeder Spalte entsprechend. Verwenden Sie KEINE "Standardgröße" für jede Spalte. Wenn Sie nur 30 Zeichen benötigen, warum erstellen Sie eine Spalte, die 255 Zeichen verarbeiten kann? Ich bin so froh, dass Sie nicht befürworten,
varchar(max)
für Ihre Zeichenfolgenspalten zu verwenden.Dies ist besonders ratsam, wenn Sie jemals eine Spalte indizieren müssen oder wenn Sie eine Spalte als Primärschlüssel verwenden und sie Fremdschlüsselreferenzen enthält. SQL Server verwendet die Größe jeder Spalte im Abfrageoptimierer, um den geschätzten Speicherbedarf für die Abfrageverarbeitung zu ermitteln. Übergroße Säulen können die Leistung beeinträchtigen.
Indizes für übergroße Spalten können zu Fehlern führen:
Der Versuch, den obigen Index zu erstellen, führt zu dieser Warnung:
900 Byte ist die maximale Schlüsselgröße für Clustered-Indizes (und Nicht-Clustered-Indizes in SQL Server 2012 und älteren Versionen). 1700 Byte ist die maximale Schlüsselgröße für nicht gruppierte Indizes in neueren Versionen von SQL Server. Wenn Sie Spalten mit einer generischen Breite wie (255) entwerfen, wird diese Warnung möglicherweise weitaus häufiger als erwartet angezeigt.
Wenn Sie an Speicherinternalen interessiert sind, können Sie den folgenden kleinen Test verwenden, um besser zu verstehen, wie SQL Server nicht komprimierte Zeilenspeicherdaten speichert.
Zuerst erstellen wir eine Tabelle, in der wir Spalten unterschiedlicher Größe speichern können:
Jetzt fügen wir eine einzelne Zeile ein:
Diese Abfrage verwendet die undokumentierten und nicht unterstützten Funktionen
sys.fn_RowDumpCracker
undsys.fn_PhyslocCracker
zeigt einige interessante Details zur Tabelle an:Die Ausgabe sieht ungefähr so aus:
Wie Sie sehen, wird der
InRowLength
Wert für jeden Wert zusammen mit dem physischen Speicherort jeder Zeile angezeigt - "file_id", "page_id" und "slot_id".Wenn wir die Werte
file_id
undpage_id
aus den obigen Abfrageergebnissen nehmen undDBCC PAGE
mit ihnen ausführen , können wir den tatsächlichen physischen Seiteninhalt sehen:Die Ergebnisse meiner Maschine sind:
quelle
Andere haben bereits darauf hingewiesen, dass die Anzahl der zum Speichern der Länge erforderlichen Bytes fest ist. Ich wollte mich in Ihrer Frage auf diesen Teil konzentrieren:
Ihre Frage ist mit Enterprise Edition gekennzeichnet, was im Allgemeinen bedeutet, dass Sie über eine angemessene Datenmenge verfügen. Oft sind Unterschiede von einem Byte pro Zeile in der Praxis nicht allzu wichtig. Die folgende Tabelle mit einer vollständig gefüllten
VARCHAR(255)
Spalte belegt beispielsweise 143176 KB Speicherplatz auf dem Datenträger:Ergebnisse:
Lassen Sie uns eine zweite Tabelle mit einer vollständig ausgefüllten
VARCHAR(256)
Spalte erstellen . Das braucht mindestens ein Byte mehr pro Zeile, oder?Ergebnisse:
Es kommt einfach so vor, dass beide Tabellen den gleichen Platz beanspruchen. Die gleiche Anzahl von Zeilen passt auf jede 8-KB-Seite. Es ist toll, dass Sie Zeit damit verbringen möchten, Ihre Anwendung zu optimieren, aber ich vermute, dass Sie sich besser auf verschiedene Bereiche konzentrieren sollten.
quelle
Die angegebene Größe des Varchar hat keinen Einfluss auf die Leistung. Die Daten können tatsächlich als Zeilenspeicher mit Seitenkomprimierung oder Zeilenkomprimierung gespeichert werden. Als Clustered Columnstore oder als speicheroptimierte Tabelle. Jedes von diesen hat unterschiedliche Leistungskompromisse, aber es spielt keine Rolle, ob Sie einen varchar (255) oder einen varchar (256) deklarieren.
quelle