Ich entwerfe eine Tabelle mit Elementen, die (möglicherweise) mehrere zehn Millionen Datensätze enthalten. Einige Elemente können erst verwendet werden, wenn sie vom Administrator "genehmigt" wurden. Mit "Verwendung" meine ich, dass solche Elemente in keiner anderen Tabelle referenziert werden, bis sie "genehmigt" sind. Bis zu 50% der Artikel können zu einem bestimmten Zeitpunkt "nicht genehmigt" werden. Aufzeichnungen können "genehmigt" werden, aber nicht umgekehrt.
Ich betrachte zwei Gestaltungsmöglichkeiten:
- ein bisschen Flagge
- eine separate Tabelle mit "nicht genehmigten" Artikeln - wenn der Artikel genehmigt wird, wird er in die "normale" Tabelle verschoben (die Erneuerung der Artikel-ID ist kein Problem).
Ich denke, die zweite Option ist viel besser. Das Bit-Flag benötigt nur ein Byte pro Zeile, ist also kein Problem. Wenn wir jedoch eine Million genehmigter und eine Million nicht genehmigter Datensätze in derselben Tabelle haben, erhöht sich die Scanzeit für Vorgänge mit genehmigten Datensätzen.
Die Frage ist: Sollte ich stattdessen die erste Option (Bit-Flag) in Betracht ziehen? Hat es in der beschriebenen Situation irgendwelche Vorteile?
WHERE status='A'
und eine Abfrage das Sagen hatWHERE status = 'A' AND (... other columns and parameters here...)
, wird der Index möglicherweise weiterhin verwendet.Antworten:
Sie können es mit partitionierten Ansichten in beide Richtungen verwenden .
Sie erstellen für jeden Status eine zugrunde liegende Tabelle, die durch Einschränkungen erzwungen wird, mit sich gegenseitig ausschließenden Werten. Dann eine Ansicht, die UNIONs die zugrunde liegenden Tabellen zusammenfasst. Auf die Ansicht oder jede Basistabelle kann explizit verwiesen werden. Wenn der Status einer Zeile in der Ansicht UPDATEd ist, löscht das DBMS ihn aus einer Basistabelle und fügt ihn in die dem neuen Status entsprechende ein. Jede Basistabelle kann unabhängig von ihrem Verwendungsmuster indiziert werden. Der Optimierer löst Indexreferenzen in eine einzelne entsprechende Basistabelle auf, wenn dies möglich ist.
Die Vorteile sind
a) flachere Indizes. Rechnen Sie jedoch mit dem Index-Fan-Out. Bei dieser Skalierung und Aufteilung zwischen Ihren Statuswerten ist es möglich, dass die Indizes in den aufgeteilten Tabellen dieselbe Tiefe haben wie in der kombinierten Tabelle.
b) Es muss kein Anwendungscode geändert werden. Die Daten erscheinen weiterhin als fortlaufendes Ganzes.
c) Zukünftige neue Statuswerte können durch Hinzufügen einer neuen Basistabelle mit Einschränkungen und erneutes Erstellen der Ansicht aufgenommen werden.
Die Kosten sind all diese Datenbewegungen; Für jede Statusaktualisierung werden zwei Seiten und zugehörige Indizes geschrieben. Es gibt viel zu tun. So viel Bewegung wird auch zu Fragmentierung führen.
quelle
Das ist eigentlich nicht so viel, wenn man bedenkt, was SQL Server effizient handhaben kann. Natürlich erinnere ich mich an einen meiner früheren Jobs, bei dem eine der größten Tabellen (ein Einzelinstanzsystem) 2 Millionen Zeilen hatte und das war der größte, mit dem ich mich jemals befasst hatte. Dann hatte der nächste Job 17 Produktionsinstanzen mit einigen Tabellen mit Hunderten von Millionen Zeilen, und alle wurden zu einem Data Warehouse mit mehreren Faktentabellen mit über 1 Milliarde Zeilen zusammengefasst. Verstehen Sie mich nicht falsch, ich verspotte nicht zig Millionen Zeilen, ich betone nur, dass SQL Server mit einem guten Datenmodell und einer ordnungsgemäßen Indizierung (und Indexpflege) viel kann .
Hmm. Das klingt nicht richtig. Die Rate der "Genehmigungen" von Einträgen ist halb so hoch wie die Rate, neue Einträge zu erhalten? Für jeweils 2 neue Einträge wird nur 1 "genehmigt"? In Ihrem Beispiel von 2 Millionen Zeilen und jeweils 1 Million für "genehmigt" und "nicht genehmigt" erwarten Sie einige Jahre später mit weiteren 10 Millionen Einträgen jeweils 6 Millionen für "genehmigt" und "nicht genehmigt"? Oder ist es so, dass die 1 Million "nicht genehmigten" etwas konstant bleiben, so dass bei 10 Millionen neuen Einträgen 11 Millionen "genehmigt" und immer noch 1 Million "nicht genehmigt" sein werden?
Das ist wahr heute , aber die Dinge ändern sich im Laufe der Zeit und so besteht immer die Möglichkeit, dass das Unternehmen beschließt, "nicht genehmigen" oder vielleicht einen anderen Status wie "archiviert" usw. Zuzulassen.
Schauen wir uns also die Auswahlmöglichkeiten an:
Flag (oder möglicherweise sogar
TINYINT
"Status")TINYINT
SpalteZwei separate Tabellen (eine für "genehmigt", eine für "nicht genehmigt")
IDENTITY
Spalte und Approved Tabelle hat Spalten - ID , die ist nicht einIDENTITY
(da es nicht benötigt wird). Daher bleiben die ID-Werte konsistent, wenn sich der Datensatz zwischen Tabellen bewegt.Persönlich würde ich mich zunächst zu der einzelnen Tabelle mit der
StatusID
Spalte beugen. Die Verwendung von zwei Tabellen scheint eine überkomplizierte, vorzeitige Optimierung zu sein. Diese Art der Optimierung kann diskutiert werden, wenn die Anzahl der Datensätze mehrere Hundert Millionen beträgt und die Indizierung keine Leistungssteigerungen bringt.quelle