Was sind die aktuellen Best Practices für die Varchar-Dimensionierung in SQL Server?

12

Ich versuche zu verstehen, wie ich am besten entscheiden kann, wie groß die varchar-Spalten sein sollen, sowohl aus Speicher- als auch aus Leistungssicht.

Performance
Aus meiner Forschung, es scheintDieses Varchar (max) sollte nur verwendet werden, wenn Sie es wirklich brauchen. Das heißt, wenn die Spalte mehr als 8000 Zeichen enthalten muss, liegt ein Grund in der fehlenden Indizierung (obwohl ich ein wenig misstrauisch gegenüber der Indizierung von Varchar-Feldern im Allgemeinen bin. Ich bin jedoch ziemlich neu in den DB-Prinzipien, also ist das vielleicht unbegründet ) und Komprimierung (eher ein Speicherproblem). Tatsächlich scheinen die Leute im Allgemeinen zu empfehlen, nur das zu verwenden, was Sie benötigen, wenn Sie varchar (n) ausführen. Übergröße ist schlecht, da Abfragen die maximal mögliche Größe berücksichtigen müssen. Es wurde jedoch auch angegeben, dass der Motor die Hälfte der angegebenen Größe als Schätzung der durchschnittlichen tatsächlichen Größe der Daten verwendet. Dies würde bedeuten, dass man aus den Daten bestimmen sollte, wie groß die durchschnittliche Größe ist, sie verdoppeln und als n verwenden sollte. Für Daten mit sehr geringer Variabilität, jedoch ungleich Null, Dies impliziert bis zu 2x Übergröße über der maximalen Größe, was viel zu sein scheint, aber vielleicht nicht? Einblicke wären willkommen.

Speicher
Nachdem ich gelesen habe, wie In-Row- und Out-of-Row-Speicher funktionieren, und bedenke, dass der tatsächliche Speicher auf tatsächliche Daten beschränkt ist, scheint mir die Wahl von n (außerdem) nur einen geringen oder keinen Einfluss auf den Speicher zu haben Stellen Sie sicher, dass es groß genug ist, um alles aufzunehmen. Selbst die Verwendung von varchar (max) sollte keinen Einfluss auf die Lagerung haben. Stattdessen könnte ein Ziel darin bestehen, die tatsächliche Größe jeder Datenzeile nach Möglichkeit auf ~ 8000 Byte zu begrenzen. Ist das eine genaue Lektüre?

Kontext
Einige unserer Kundendaten schwanken geringfügig, daher machen wir Spalten im Allgemeinen nur ein wenig breiter, als sie für diese Spalten beispielsweise 15 bis 20% größer sein müssen. Ich fragte mich, ob es noch andere spezielle Überlegungen gab. Zum Beispiel sagte mir jemand, mit dem ich zusammenarbeite, ich solle 2 ^ n - 1 Größen verwenden (ich habe jedoch keine Beweise dafür gefunden, dass dies eine Sache ist ...)

Ich spreche von der ersten Tabellenerstellung. Ein Kunde teilt uns mit, dass er uns eine neue Tabelle senden und Beispieldaten (oder nur den ersten Produktionsdatensatz) senden wird, die wir uns ansehen und an unserem Ende eine Tabelle erstellen, um die Daten zu speichern. Wir möchten die Tabelle an unserem Ende erstellen, um zukünftige Importe sowie die Angaben in der Stichprobe zu behandeln. Bestimmte Zeilen werden jedoch zwangsläufig länger, daher füllen wir sie auf.

Die Frage ist, wie viel und gibt es technische Richtlinien?

aristotle2600
quelle
MongoDB verwendet die 2 ^ n-Festplattenzuordnung für ein Dokument. SQL Server verwendet diese Strategie nicht.
Michael Green

Antworten:

18

Unabhängig vom spezifischen Datentyp müssen Sie in der Lage sein, alle zu speichernden Anwendungsanforderungen zu speichern. Sie können nichts kleineres als die maximale Größe der tatsächlich gespeicherten Daten angeben.

Sie müssen und möchten auch keine Spaltenlänge angeben, die größer ist als die maximale tatsächliche Größe, die aus verschiedenen Gründen gespeichert wird: Zuweisung des Abfragespeichers, möglicherweise Ausfüllen der maximalen Zeilengröße und kein Platz zum Hinzufügen von Spalten die Zukunft usw.

Es stimmt, Zeichenkette variabler Länge und binäre Spalten nicht über die Speicher Implikation , dass mit fester Länge Datentypen (string / Binär / numerisch / Datum / etc) tun (obwohl, können einige dieser Auswirkungen durch Datenkomprimierung oder Verwendung der zunichte gemacht werden SPARSESpaltendefinition Möglichkeit). Wie Sie bereits betont haben, besteht jedoch auch dann keine Auswirkung auf die Leistung, wenn der erforderliche Speicher für Abfragen überschätzt wird, wenn keine direkten Auswirkungen auf den Speicher vorliegen.

Empfindlich sein. Benutze nur was du brauchst. Überlegungen können angestellt werden, wenn eine hohe Wahrscheinlichkeit besteht, dass die Spaltenlänge in naher Zukunft erhöht werden muss. Beachten Sie jedoch, dass es einfacher ist, die Größe einer Spalte zu erweitern, als die Größe zu verringern. Ja, einige Arbeiten werden involviert sein, aber da diese Arbeit lediglich "potenziell" ist, während die Auswirkungen einer Übergröße auf die Leistung "tatsächlich" sind, ist es oft am besten, Spalten basierend auf dem zu definieren, was Sie tatsächlich benötigen, und nicht auf dem, was Sie vielleicht irgendwie tun -sorta denke, Sie könnten in der Zukunft brauchen. Viele Änderungen, über die gesprochen wird, treten nie auf, und oft sind die erforderlichen Änderungen nicht vorhersehbar. Geh mit dem, was du weißt.

Stattdessen könnte ein Ziel darin bestehen, die tatsächliche Größe jeder Datenzeile nach Möglichkeit auf ~ 8000 Byte zu begrenzen.

Ich bin mir nicht ganz sicher, was Sie hier vorhaben. SQL Server beschränkt Sie physisch auf etwas mehr als 8000 Byte. Verwendung LOB - Typen - VARCHAR(MAX), NVARCHAR(MAX), VARBINARY(MAX), XML, und die als veraltete TEXT, NTEXTund IMAGETypen - ermöglichen darüber hinaus , dass die erste Seitengröße Begrenzung geht, aber das ist nur aufgrund eines Zeigers Plazieren (16 oder mehr Bytes, von der Art abhängig, und je nach dem Größe des Werts, der bei Verwendung der MAXTypen außerhalb der Zeile gespeichert wird ). Das tatsächliche physikalische Limit der Datenseite hat sich nicht geändert.

Ihr Ziel sollte es sein, möglichst wenig physischen Speicherplatz zu verwenden, um das zu speichern, was die App / das Unternehmen zum Speichern benötigt, ohne zu brechen oder abzuschneiden, sodass der unvollständige Wert an Bedeutung verliert oder nachgelagerte Probleme verursacht. Wenn Sie ein Ding mit 12.000 Zeichen speichern müssen, verwenden Sie es, VARCHAR(MAX)da dies erforderlich ist. Wenn Sie eine Telefonnummer oder Postleitzahl speichern, ist die Verwendung unklug VARCHAR(100)und unverantwortlich VARCHAR(MAX).

Einige unserer Kundendaten schwanken ein wenig, daher machen wir Spalten im Allgemeinen nur ein wenig breiter, als sie für diese Spalten beispielsweise 15 bis 20% größer sein müssen. Ich fragte mich, ob es noch andere spezielle Überlegungen gab.

Haben nicht alle Systeme mindestens einige Daten, die schwanken? Jedes System, das den Namen einer Person speichert, würde sich qualifizieren, oder? Es gibt eine ziemlich große Varianz in der Länge von Namen. Und dann muss jemand wie Prince seinen Namen in ein Symbol ändern, und jetzt haben Sie ein ganz anderes Problem, das nicht lang ist. So sind die Dinge eben.

Aber um für einen Moment den Anwalt des Teufels zu spielen: Wie kann der Wert "15-20% größer als benötigt" nicht der tatsächlich benötigte Wert sein? Nehmen wir an, es gibt eine Diskussion über das Hinzufügen einer neuen Spalte, und jemand schlägt 50 Zeichen vor. Dann sagt jemand anderes: "Nun, 20% mehr sind 60, also machen wir 60, weil jemand 60 haben könnte." Wenn es stimmt, dass ein Kunde 60 hat, dann ist und war 60 immer der tatsächlich benötigte Wert, und 50 war die ganze Zeit falsch.

Natürlich wäre es hilfreich, wenn es Hinweise auf die Datenquelle gäbe, weil:

  1. Wenn Sie "URL" 1024 erstellen und jemand 1060 benötigt, muss es 1060 sein (ähnlich, wenn Sie eine URL erstellen VARCHARund Beschwerden erhalten, dass Unicode-Zeichen durcheinander gebracht werden, die jetzt in Domain-Namen zulässig sind, muss dies der Fall sein NVARCHAR). aber
  2. wenn jemand will 1000 Zeichen in ein 500 Zeichen-Limit Kommentarfeld an, dann noch es nur benötigt 500 Menschen werden weniger ausführlich in den Kommentaren werden können (eine große Herausforderung für mich ;-), aber ProductSKUbesser groß genug sein , um alle zu passen der SKUs des Kunden.

Ich spreche von der ersten Tabellenerstellung. Ein Kunde wird uns mitteilen, dass er uns eine neue Tabelle senden und Beispieldaten (oder nur den ersten Produktionsdatensatz) senden wird, die wir uns ansehen und an unserem Ende eine Tabelle erstellen, um die Daten zu speichern. Wir möchten die Tabelle an unserem Ende erstellen, um zukünftige Importe sowie die Angaben in der Stichprobe zu behandeln. Bestimmte Zeilen werden jedoch zwangsläufig länger, daher füllen wir sie auf. Die Frage ist, wie viel und gibt es technische Richtlinien?

Sie machen hier viele Annahmen. Sicher, einige Felder könnten größer werden. Aber vielleicht auch nicht. Oder einige könnten kleiner werden. Einige können von Nicht-Unicode zu Unicode wechseln (sobald sie feststellen, dass die Welt kleiner wird und man nicht davon ausgehen kann, dass Nachnamen immer nur grundlegende ASCII / US-Englisch-Zeichen haben). Oder sie könnten aufhören, ein Feld zu senden. Oder sie können in Zukunft ein oder mehrere Felder hinzufügen. Jede Kombination von diesem und anderen Dingen. Warum also nur auf VARCHARSpalten konzentrieren? Was ist, wenn sie gerade einen INTWert senden und in ein oder zwei Jahren den Maximalwert erreichen und mit dem Senden eines Werts beginnen BIGINT? Was ist, wenn sie ein "Status" -Feld mit den Werten 0 - 5 haben? Gehen Sie einfach davon ausINTWas ist "gepolstert", da es Wachstum ermöglicht, sollte es aber wahrscheinlich sein TINYINT?

Das einzige, was Sie sicher vorhersagen können, ist, dass der Versuch, vorherzusagen, wie sich die Daten Ihrer Kunden ändern werden, häufiger falsch als richtig ist. Und richtig zu sein ist eine Frage des Glücks / Zufalls (wenn nicht des Glücks, dann spielen Sie einfach Lotto;).

Die Richtlinie lautet also:

  1. Verschwenden Sie keine Zeit und Energie damit, eine unbeantwortbare Frage zu beantworten.
  2. Konzentrieren Sie sich stattdessen darauf, so viele Informationen wie möglich über die tatsächlichen Daten Ihres Kunden zu erhalten, und gehen Sie damit um (dh datengesteuerte Entscheidungsfindung ;-).

Sie haben bereits Beispieldaten, großartig. Vergessen Sie jedoch nicht, dass Sie auch die Kontaktinformationen Ihres Kunden haben: Telefon und / oder E-Mail. Kontaktiere Sie! Fragen Sie sie nach ihren Datenspezifikationen (genau wie Ihr System können die Daten, die sich derzeit in ihrem System befinden, eine maximale Länge von 35 haben, aber ihr System hat sie als definiert VARCHAR(50), und ihr System akzeptiert bis zu dieser Länge. In diesem Fall sollten Sie sie verwenden 50). Fragen Sie sie, ob sie kurzfristige Änderungspläne für diese Datentypen (Typ und / oder Größe) haben.

Solomon Rutzky
quelle
1
Ich stimme Solomon zu, @ Aristotle2600 - Sie können jedoch einen Blick auf meine Antwort auf eine Frage bezüglich der Unterschiede zwischen a varchar(255)und a varchar(256)
Max Vernon
Vielen Dank, ich hatte den Eindruck, dass es so etwas sein würde, und "nur das verwenden, was Sie brauchen" ist einfach eine gute Praxis für das Ressourcenmanagement. Einige unserer Kundendaten schwanken jedoch geringfügig, sodass wir Spalten im Allgemeinen nur ein wenig breiter machen, als sie für diese Spalten beispielsweise 15 bis 20% größer sein müssen. Ich fragte mich, ob es noch andere spezielle Überlegungen gab. Zum Beispiel sagte mir jemand, mit dem ich zusammenarbeite, ich solle 2 ^ n - 1 Größen verwenden (ich habe jedoch keine Beweise dafür gefunden, dass dies eine Sache ist ...). Aber es hört sich so an, als gäbe es nichts anderes, als die Dinge so klein wie möglich zu halten.
Aristoteles2600
1
@ aristotle2600 Sie sind sich nicht sicher, wie Sie "2 ^ n - 1" anwenden sollen, aber ich müsste trotzdem fragen: Ist es überhaupt theoretisch möglich, etwas größer zu machen, als es sein muss ? Wäre diese 15-20% größere Größe nicht die Größe, die es sein müsste , um nicht zu brechen? ;-). Ich bin sicher, es würde helfen, wenn Sie in der Quelle der Daten expliziter wären, denn a) wenn Sie "URL" 1024 machen und jemand 1060 benötigt, dann müsste es 1060 sein, aber b) wenn jemand 1000 hinzufügen möchte Zeichen auf ein 500 Zeichen-Limit Kommentarfeld, dann noch es nur benötigt 500 Menschen geben wenige Kommentare können sein, aber Produkt SKU besser groß genug sein.
Solomon Rutzky
@ aristotle2600 Ich habe gerade einige Ihrer Kommentare hier in die Frage eingefügt, da sie einen guten Kontext bieten. Ich habe auch Sachen am Ende meiner Antwort hinzugefügt :)
Solomon Rutzky
Vielen Dank für Ihre Antwort! Ja, Namen und Adressen schwanken. Was das immer größer werdende 20% -Paradox betrifft, verstehe ich, was Sie meinen, aber ich spreche von der anfänglichen Tabellenerstellung. Ein Kunde wird uns mitteilen, dass er uns eine neue Tabelle senden und Beispieldaten (oder nur den ersten Produktionsdatensatz) senden wird, die wir uns ansehen und an unserem Ende eine Tabelle erstellen, um die Daten zu speichern. Wir möchten die Tabelle an unserem Ende erstellen, um zukünftige Importe sowie die Angaben in der Stichprobe zu behandeln. Bestimmte Zeilen werden jedoch zwangsläufig länger, daher füllen wir sie auf. Die Frage ist, wie viel und gibt es technische Richtlinien?
Aristoteles2600