Indizierungsleistung BigInt vs VarChar

7

Dies ist eine FACT-Tabelle in einem Data Warehouse

Es hat einen zusammengesetzten Index wie folgt

%Vor%

In dieser Struktur haben alle varchar 10-Spalten nur numerische Werte. Wird es für mich vorteilhaft sein, diese 78 Millionen Zeilenstruktur zu ändern, um BIGINT statt VARCHAR in Bezug auf Abfrage und Indizierung zu halten?

Irgendwelche anderen Vorteile / Nachteile, die ich berücksichtigen sollte?

    
Raj More 21.10.2009, 20:40
quelle

3 Antworten

14

Sie sollten DEFINITIV einen Surrogat INT IDENTITY() Primärschlüssel einführen !! INT gibt Ihnen möglicherweise bis zu 2 Milliarden Zeilen - ist das nicht genug?

Dieser Primärschlüssel / Clusterschlüssel auf SQL Server hat eine Größe von bis zu 64 Byte (anstelle von 4 für einen INT). Dadurch wird Ihr Clustered-Index UND Ihr gesamter Nicht-Clustered-Index bis zur Unkenntlichkeit aufgebläht. Der gesamte Cluster-Schlüssel (alle Ihre 8 Spalten) wird auf jeder einzelnen Seite jedes einzelnen nicht gruppierten Indexes auf dieser Tabelle enthalten sein - was sehr viel Platz verschwenden wird.

In jeder gegebenen Indextabelle hätten Sie also bis zu 16 Mal mehr Einträge mit einem Ersatz-INT-Clusterschlüssel - das bedeutet viel weniger I / O, viel weniger Zeitverschwendung beim Lesen von Indexseiten.

Und stellen Sie sich vor, eine Fremdschlüsselbeziehung zu dieser Tabelle herzustellen ... Jede untergeordnete Tabelle müsste alle 8 Spalten Ihres Primärschlüssels als Fremdschlüsselspalten haben und alle angeben 8 Spalten in jeder Verbindung - was für ein Albtraum !!

Bei 78 Millionen Zeilen sparen Sie sogar durch Ändern des Clustering-Schlüssels auf INT IDENTITY bis zu 60 Byte pro Zeile - allein das würde bis zu 4 GByte Speicherplatz (und RAM-Auslastung auf Ihrem Server) ausmachen. Und das ist noch nicht einmal am Anfang, um die Einsparungen für die nicht geclusterten Indizes zu berechnen .......

Und natürlich, ja, ich würde auch das VARCHAR (10) in INT oder BIGINT ändern - wenn es eine Zahl ist, mach das Feld numerisch - kein Punkt, der es bei VARCHAR (10) wirklich belassen soll. Aber das alleine wird keinen großen Unterschied in Bezug auf Geschwindigkeit oder Leistung machen - es macht nur das Arbeiten mit den Daten viel einfacher (muss nicht immer zu numerischen Typen wechseln, wenn zB Werte verglichen werden usw.) / p>

Marc

    
marc_s 21.10.2009, 20:43
quelle
4

Zwei Dinge, die die Leistung des Index (und der gesamten Datenbank) beeinflussen können:

1) Größe der Indexseite 2) Vergleichsgeschwindigkeit

Im ersten Fall gilt: Je kleiner Ihre Index- / Datenseite ist, desto mehr Seiten können Sie im Speicher halten, und desto größer ist die Wahrscheinlichkeit, dass eine bestimmte Abfrage die Seite im Cache finden kann Scheibe. Daher sollten Sie den kleinsten Datentyp verwenden, der Ihre bestehenden und zukünftigen Anforderungen problemlos erfüllen kann.

BigInt ist 8 Bytes; Die VARCHARs können kleiner sein, wenn die Größe der Daten klein ist, also hängt es wirklich von Ihren Daten ab. Es kann jedoch vorkommen, dass 10 Zeichen lange Zahlen in den SQL Server-INT-Datentyp ( Ссылка ) passen auf die Größe, so int vs. bigint hängt von Ihrer Domain ab.

Auch wenn Ihre gesamte Zeile eine feste Länge hat, gibt es einige Optimierungen, die SQL Server in Scans durchführen kann, da es genau weiß, wo auf der Festplatte die nächste Zeile sein wird (vorausgesetzt, die Zeilen sind zusammenhängend). Ein Randfall, um sicher zu sein, aber es kann helfen.

Bei der zweiten Methode ist es schneller, ganze Zahlen zu vergleichen als Unicode-Strings. Wenn Sie also nur Zahlenwerte speichern, sollten Sie auf jeden Fall zu einem numerischen Datentyp mit geeigneter Größe wechseln.

Schließlich hat Marc Recht, dass dies ein sehr verschlungener Primärschlüssel wird. Wenn Ihre Daten dies jedoch rechtfertigen - wie zum Beispiel, dass dies Ihre EINZIGEN Spalten sind und Sie nie zusätzliche Abfragen durchführen -, können Sie vollkommen in Ordnung sein, indem Sie die optimierte Version (mit Bigints usw.) zu Ihrem Primärschlüssel machen. Irgendwie ein Code-Geruch, also werde ich seinen Ratschlag wiederholen, um wirklich ein Blick auf Ihr Datenmodell zu werfen und zu sehen, ob das korrekt ist.

    
Matt Rogish 21.10.2009 21:02
quelle
1

Marc S hat Recht damit, dass der 64-Byte-Primärschlüssel in jeden NC-Index dupliziert wird, so dass Sie E / A-Kosten zahlen müssen, was sich auf die Menge der Daten auswirkt, die im Speicher gehalten werden (seit Sie verschwenden Speicherplatz auf einer NC-Indexseite). Auf dieser Basis lautet die Frage also nicht "Soll ich meine Varchare konvertieren", sondern "sollte ich meinen Clustered Index in etwas ganz anderes konvertieren" ./

In Bezug auf den Varchar vs Bigint gibt es einen guten Grund zu konvertieren, wenn Sie sich die Zeit leisten können; Das ist außerhalb des 2-Byte-Unterschieds im Speicher pro Feld. Wenn Sie Werte zweier verschiedener Typen vergleichen, wird SQL gezwungen, eine davon zu konvertieren. Dies würde bei jedem einzelnen Vergleich auftreten, egal ob es sich um einen Index-Join oder ein Prädikat innerhalb einer Where-Klausel handelt.

Je nachdem, für was Sie die Daten auswählen, welche Dimensionstabellen mit der Faktentabelle verknüpft sind, könnten Sie die Conversion-Overhead-Kosten für jede einzelne Abfrage aufheben, da sie eine Seite davon konvertieren muss .

    
Andrew 21.10.2009 20:59
quelle