Nehmen leere Spalten Platz in einer Tabelle ein?


20

Ich habe Tabelle, die von sehr grundlegenden Informationen hält. Nur ein Titel und ein paar Datumsfelder. Es gibt ein Feld namens " Kommentare", das varchar (4000) ist. Meistens lassen wir es leer, aber manchmal geben wir hier eine große Datenmenge ein. Ist das ein wirklich schlechtes Design? Oder ist das nur ein bisschen ineffizient?

Ich würde davon ausgehen, dass das Erstellen einer separaten Tabelle für diese Spalte besser wäre.

Hinweis: Dies ist SQL Server 2008

Bildbeschreibung hier eingeben


Vielen Dank für Ihr Feedback an alle! Ich beschloss, es einfach zu halten und die Spalte in der Tabelle zu belassen und nicht in eine andere Tabelle zu stellen. Allerdings habe ich die SPARSE-Funktion in SQL 2008 verwendet, sodass für das Feld kein Leerzeichen verwendet wird.

2
Nur neugierig, was ist "die meiste Zeit"? Wie viele Zeilen insgesamt und wie viel Prozent haben hier einen Wert? Ich frage mich nur, ob Sie vorhaben, Platz- / Leistungsvergleiche mit SPARSEund ohne SPARSE...
durchzuführen

Antworten:


9

Um eine vorhersehbarere Leistung zu erzielen (und um zu vermeiden, dass die Zeilen pro Seite stark variieren), würde ich diese Daten gerne in einer verwandten Tabelle speichern - insbesondere, wenn sie nur zu einem geringen Prozentsatz gefüllt sind und insbesondere, wenn sie nur in abgerufen werden einige der Abfragen. Die Zeilen, in denen dieser Wert angegeben ist NULL, tragen zwar zum Platzbedarf bei, dies ist jedoch minimal. Wichtiger wird sein, wie eine Seite möglicherweise nur zwei Zeilen und die nächste 500 Zeilen aufnehmen kann - dies kann sich sehr auf die Statistik auswirken, und Sie sollten dies besser aufteilen, damit es separat gespeichert wird und sich nicht auf alle Vorgänge auswirkt die Kerntabelle.


12

Es nimmt nur wenig Platz in Anspruch, wenn es nicht verwendet wird

  • ein Bit in der NULL-Bitmap
  • zwei Bytes für die Länge (die Null sein wird, wenn NULL)

Der Overhead ist minimal und die Optimierung wird verfrüht sein.

Bis Sie wissen, dass Sie ein Problem haben, bewahren Sie es einfach in einer Tabelle auf. Sie unterbrechen KISS, indem Sie äußere Verknüpfungen einführen und einen zusätzlichen Aufwand beim Abfragen der Daten verursachen.

Siehe /programming/3793022/how-to-come-to-limits-of-8060-bytes-per-row-and-8000-per-varchar-nvarchar-valu/3793265#3793265 für mehr


10

Ich denke, eine separate Tabelle ist besser, um die Seitendichte zu verbessern und die Fragmentierung zu reduzieren, besonders wenn Sie dieses Feld nicht immer füllen.

  • Eine Datenseite enthält ungefähr 8000 Bytes
  • Sie haben einige Zeilen mit beispielsweise 100 Bytes und einige Zeilen mit über 4000 Bytes
  • Diese langen Zeilen befinden sich auf einer Seite für sich und der Rest der Seite ist "verschwendeter" Speicherplatz, den Ihre Datenbank belegt, der aber wahrscheinlich niemals Daten enthält
  • Wenn Sie diesem langen Feld Daten für einen Datensatz auf einer größtenteils vollständigen Seite hinzufügen, wird die Seite wahrscheinlich überlaufen und ein Zeiger auf die Seite mit dem Rest des Datensatzes angezeigt

All diese leeren Seiten und Zeiger führen zu einer schlechten Leistung. Normalisieren Sie dieses Feld, wenn Sie können.


4

Diese Frage sieht sehr ähnlich aus: Beeinflussen zusätzliche leere Spalten die SQL-Tabellengröße erheblich?

Es sieht so aus, als ob die Antwort lautet: Ja, es nimmt zwar Platz in Anspruch, aber es gibt einen Komprimierungsalgorithmus für Spalten mit vielen Nullwerten.

In Bezug auf das Design denke ich, dass eine externe Tabelle, die mit dieser verknüpft ist, ein saubereres Design wäre. Eine Spalte mit häufigen Nullwerten macht es den Benutzern der Datenbank schwerer, da sie versehentlich einen Nullwert verwenden könnten, wenn sie nicht vorsichtig sind. Daher müsste der Code, der die Datenbank verwendet, eine Fehlerprüfung enthalten, und von dort aus wird er nur hässlich.


2
Der Komprimierungsalgorithmus gilt explizit nur für die Spalten, die explizit als SPARSE"Spalten mit vielen Nullwerten" definiert sind.
Aaron Bertrand

2

Sie werden in Ordnung sein - es ist bereits eine Varchar-Spalte, daher wird nur dann Speicherplatz verwendet, wenn sie Daten enthält. Wenn Sie viele nullfähige Spalten mit fester Größe wie int hatten, kann es zu Problemen bei der Speicherplatznutzung kommen.

Soweit ich es in einen anderen Tisch stelle, würde ich mich nicht darum kümmern. Sie können sich auch die Verwendung von varchar (max) und die Optionen zum Ein- und Ausreihen ansehen. Wieder wahrscheinlich verfrüht.


1
Eine vorzeitige Optimierung kann oft ein echtes Problem sein, das jedoch von den Kosten für ein späteres Refactoring abhängt. Wenn Sie heute wissen, dass nur 1% Ihrer Zeilen Daten in dieser Spalte enthalten, und Sie davon ausgehen, dass die Tabelle im Laufe der Zeit größer wird, wie hoch ist der Wert, wenn Sie diese Daten in der aktuellen Tabelle beibehalten, um bei der Skalierung Konsequenzen zu haben? Ich bin alle dafür, vorzeitige Optimierung zu vermeiden, aber es gibt einen Punkt, an dem ich die langfristigen Auswirkungen abwäge.
Aaron Bertrand

@ Aaron Bertrand Einverstanden. Die Leute stellen hier Leistungsfragen und es ist leicht anzunehmen, dass sie eine App haben, die Millionen von Zeilen umfasst. Sie müssen jede Waffe im Toolkit verwenden und all dies berücksichtigen. Andererseits scheint der Benutzer manchmal am Anfang einer Lernkurve zu stehen, und es ist schwierig, ihn zu bitten, Zeit für etwas zu investieren, das wahrscheinlich weniger wichtig für ihn ist. Mit varchar (max) können Sie auch effektiv einen Schalter betätigen, um das Speichern außerhalb der Reihe zu starten. Ich denke, die eigentliche Antwort lautet: "Sie haben uns nicht wirklich genug Informationen gegeben, um eine endgültige Antwort zu geben."
Cade Roux
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.