Frage

Bis jetzt habe ich die C # unter Verwendung von "Guid = Guid.NewGuid ();" Verfahren eine eindeutige ID zu erzeugen, die als ID-Feld in einigen meiner SQL Server-Datenbank-Tabellen mit Linq to SQL gespeichert werden können. Ich habe für die Indizierung von Gründen mitgeteilt, dass eine GUID eine schlechte Idee ist und dass ich ein automatische Erhöhung Lange stattdessen verwenden. Wird durch die Verwendung meiner Datenbank-Transaktionen eine lange beschleunigen? Wenn ja, wie gehe ich über die eindeutige ID der zu erzeugen, die vom Typ ist lange?

Grüße,

War es hilfreich?

Lösung

Beide haben Vor- und Nachteile, es kommt ganz auf, wie Sie sie, dass Angelegenheiten verwenden.

Rechts von der Fledermaus, wenn Sie Identifikatoren müssen, die sich über mehrere Datenbanken arbeiten können, müssen Sie GUIDs. Es gibt einige Tricks, mit Long (manuell jeder Datenbank eine andere Seed / Schritt Zuweisung), aber diese skalieren nicht gut.

Was Indizierung geht, wird noch lange gibt viel besser Einfügeleistung, wenn der Index geclustert (standardmäßig Primärschlüssel geclustert werden, aber dies kann für die Tabelle geändert werden), da der Tisch muss nicht nach jedem neu organisiert werden einfügen.

Soweit gleichzeitige Einsätze jedoch besorgt sind, Long (Identität) Spalten langsamer als GUID sein - Identitätsspalte Generation erfordert eine Reihe von exklusiven Sperren, um sicherzustellen, dass nur eine Zeile der nächste laufende Nummer bekommt. In einer Umgebung mit vielen Benutzern viele Zeilen die ganze Zeit eingesetzt wird, kann dies eine Performance Hit. GUID Generation ist in dieser Situation schneller.

Speicher weise findet eine GUID zweimal den Raum eines Lang bis (8 Byte vs 16). Doch es auf der Gesamtgröße Ihrer Zeile hängt, wenn 8 Byte wird einen spürbaren Unterschied in machen, wie viele Datensätze passen in einem Blatt, und damit die Anzahl der Blätter von der Platte während einer durchschnittlichen Anfrage gezogen.

Andere Tipps

Ein langes (big int in SQL Server) ist 8 Byte und ein Guid ist 16 Bytes, so dass Sie die Anzahl der Bytes SQL Server Halbieren zu vergleichen hat, wenn Sie einen Blick nach oben zu tun.

Für eine lange, Verwendung IDENTITY Erzeugung (1,1), wenn Sie das Feld in der Datenbank erstellen.

so entweder Tabelle erstellen oder Tabelle ändern:

Field_NAME BIGINT NOT NULL PRIMARY KEY IDENTITY(1,1)

Siehe Kommentare zu veröffentlichen LINQ to SQL

Die "Queen of Indexing" - Kim Tripp - im Grunde sagt sie alle in ihrem Indizierung Blog-Beiträge:

Im Grunde ihre Best Practices sind: ein optimaler Gruppierungsschlüssel sein sollte:

  • unique
  • kleine
  • stabil (nie zu ändern)
  • ständig wachsende

GUID verletzt die „kleine“ und „immer größer werdenden“ und somit nicht optimal.

PLUS: alle Cluster-Schlüssel werden zu jedem hinzugefügt werden und jeder einzelne Eintrag in jeder und jedem einzelnen nicht gruppierten Index (als Lookup, um tatsächlich den Datensatz in der Datenbank zu finden), so dass man sie so klein machen wollen als möglich (INT = 4 Byte vs. GUID = 16 Byte). Wenn Sie Hunderte von Millionen von Zeilen und mehrere nicht gruppierten Indizes, eine INT oder BIGINT über eine GUID Auswahl kann einen großen Unterschied machen -. Auch nur platz weise

Marc

guids verwenden, wenn Sie Import / Export auf mehrere Datenbanken müssen prüfen. Guids ist oft leichte Spalten zu verwenden, als das Identity-Attribut angeben, wenn mit einem Datensatz von mehreren Kind-Beziehungen zu arbeiten. dies liegt daran, dass Sie nach dem Zufall guids im Code in einem getrennten Zustand aus der Datenbank, und dann reichen Sie alle Änderungen auf einmal generieren. Wenn guids richtig erzeugt werden, sind sie insainely schwer zufällig zu duplizieren. Mit Identitätsspalten, haben Sie oft eine intial Einsatz einer übergeordneten Zeile und Abfrage zu tun für sie vor dem Hinzufügen von Child-Daten neue Identität ist. Sie haben dann alle untergeordneten Datensätze mit der neuen Mutter Identität zu aktualisieren, bevor sie in die Datenbank zu begehen. Das gleiche gilt für die Enkelkinder und so weiter bis der Hierarchie. Es baut auf eine Menge Arbeit auf die unnötige und banal scheint. Sie können ohne die Identity-Spezifikation mit Zufallszahlen von comming up etwas ähnliches wie Guids tun, aber die Chance einer Kollision stark erhöht, wie Sie mehr Aufzeichnungen über die Zeit ein. (Guid.NewGuid () ist ähnlich wie bei einem zufälligen Int128 - die noch nicht existiert).

Ich benutze Byte (TinyInt), Int16 (SmallInt), Int32 / UInt16 (Int), Int64 / UInt32 (BigInt) für kleine Lookup-Listen, die ändern oder Daten nicht, die nicht zwischen mehreren Datenbanken repliziert. (Berechtigungen, Anwendungskonfiguration, Farbnamen, etc.)

Ich stelle mir die Indizierung nur so lange dauert gegen unabhängig abzufragen, wenn Sie eine GUID oder eine lange verwenden. Es gibt in der Regel andere Felder in Tabellen, die indiziert sind, die größer als 128 Bits sowieso (Benutzernamen in einer Benutzertabelle zum Beispiel). Der Unterschied zwischen Guids und ganzen Zahlen ist die Größe des Index im Speicher, sowie Zeit bevölkern und der Wiederaufbau Indizes. Die Mehrzahl der Datenbanktransaktionen ist oft zu lesen. Das Schreiben ist minimal. Konzentrieren Sie sich auf der Optimierung von der Datenbank zu lesen zuerst, wie sie in der Regel von verknüpften Tabellen vorgenommen werden, die nicht richtig optimiert wurde, unsachgemäßen Paging oder fehlenden Indizes.

Wie bei allem, das Beste, was zu tun ist, um zu beweisen. eine Testdatenbank mit zwei Tabellen erstellen. Eine mit einem Primärschlüssel der ganzen Zahlen / Long-Positionen, und die andere mit einem guid. Bevölkern der jeweils mit N-Million Zeilen. Moniter die Leistung von jeweils während der CRUD-Operationen (Erstellen, Lesen, Aktualisieren, Löschen). Sie können herausfinden, dass es einen Leistungseinbruch hat, aber unbedeutend.

Server laufen oft auf Boxen ohne Umgebungen und andere Anwendungen Debuggen Aufnahme CPU, Speicher und I / O auf der Festplatte (vor allem mit RAID). Eine Entwicklungsumgebung gibt Ihnen nur eine Vorstellung von Leistung.

Sie können den ganzen Tag GUID oder Identität diskutieren. Ich ziehe die Datenbank den einzigartigen Wert mit einer Identität zu erzeugen. Wenn Sie Daten aus mehreren Datenbanken zusammenführen, fügen Sie eine weitere Spalte (die Quelldatenbank zu identifizieren, die möglicherweise eine tinyint oder smallint) und einen zusammengesetzten Primärschlüssel bilden.

Wenn Sie mit einer Identität gehen Sie, müssen Sie den richtigen Datentyp wählen, basierend auf der Anzahl der erwarteten Schlüssel werden Sie generieren:

bigint - 8 Bytes - max positive value: 9,223,372,036,854,775,807  
int    - 4 Bytes - max positive value:             2,147,483,647

Hinweis „Anzahl der erwarteten Schlüssel“ ist anders als die Anzahl der Zeilen. Wenn Sie in erster Linie Zeilen hinzufügen und halten, können Sie feststellen, dass ein INT mit über 2 Milliarden eindeutige Schlüssel genug ist. Ich wette, Ihre Tabelle nicht so groß bekommen. wenn Sie eine hohe Volumentabelle jedoch, wo Sie halten das Hinzufügen und Entfernen von Zeilen, Zeilen Sie Zahl niedrig sein kann, aber Sie werden schnell durch Tasten gehen. Sie sollten einige Berechnungen, um zu sehen, wie log es dauern würde, durch die INTs 2000000000 Tasten gehen. Wenn es sie nicht bald mit INT gehen zu jeder Zeit aufbrauchen, da sonst die Schlüsselgröße verdoppeln und geht mit BIGINT.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top