Ich bin nach einiger Bestätigung dieser Idee, eine schlecht funktionierende Datenbank zu reparieren oder einen besseren Vorschlag, falls einer eine hat. Immer offen für bessere Vorschläge.
Ich habe eine sehr große Datenbank (mehr als 20 Millionen Datensätze, die um ungefähr eine halbe Million pro Tag wachsen), die GUID als PK verwenden.
Ein Versehen meinerseits, aber die PK ist auf SQL Server geclustert und verursacht Leistungsprobleme.
Der Grund für eine Guid: Diese Datenbank ist teilweise mit 150 anderen Datenbanken synchronisiert, sodass die PK eindeutig sein musste. Die Synchronisierung wird nicht von SQL Server verwaltet, sondern es wird ein benutzerdefinierter Prozess erstellt, der die Daten für die Anforderungen des Systems synchronisiert - und zwar basierend auf dieser GUID.
In jeder der 150 entfernten Datenbanken werden nicht die vollständigen Daten gespeichert, die in der zentralen SQL-Datenbank gespeichert sind. Sie speichern nur eine Teilmenge der Daten, die sie tatsächlich benötigen, und die Daten, die sie benötigen, sind nicht eindeutig für sie (10 der 150 Datenbanken enthalten möglicherweise einige der gleichen Datensätze aus Datenbanken anderer Sites, die sie beispielsweise gemeinsam nutzen). Außerdem werden die Daten tatsächlich an den entfernten Standorten und nicht an der zentralen Stelle generiert, weshalb die GUIDs erforderlich sind.
Die zentrale Datenbank wird nicht nur verwendet, um alles synchron zu halten, sondern es werden auch Abfragen von mehr als 3000 Benutzern für diese sehr große fragmentierte Datenbank ausgeführt. Bereits beim ersten Testen ist dies ein großes Problem.
Zum Glück sind wir noch nicht live - also kann ich Änderungen vornehmen und bei Bedarf Dinge offline schalten, was zumindest etwas ist.
Die Leistung der entfernten Datenbanken ist kein Problem - die Datenteilmengen sind ziemlich klein und die Datenbank wird in der Regel nie größer als 1 GB. Die Datensätze werden regelmäßig an das Hauptsystem zurückgespeist und von den kleineren BDs entfernt, wenn sie nicht mehr benötigt werden.
Die Leistung der zentralen Datenbank, in der alle Datensätze gespeichert sind, ist bedauerlich - aufgrund einer gruppierten GUID als Primärschlüssel für die vielen Datensätze. Die Indexfragmentierung ist nicht in den Diagrammen.
Meine Überlegungen zur Behebung des Leistungsproblems sind, eine neue Spalte zu erstellen - Unsigned BIGINT IDENTITY (1,1) und dann die Clustered PK der Tabelle BIGINT-Spalte zu ändern.
Ich würde einen eindeutigen nicht gruppierten Index auf dem GUID-Feld verursachen, das der Primärschlüssel war.
Die kleineren entfernten 150-Datenbanken müssen nichts über die neue PK in der Central SQL Server-Datenbank wissen. Sie wird lediglich zum Organisieren der Daten in der Datenbank und zum Unterbinden der schlechten Leistung und Fragmentierung verwendet.
Würde dies funktionieren und die Leistung der zentralen SQL-Datenbank verbessern und die zukünftige Hölle der Indexfragmentierung (bis zu einem gewissen Grad) verhindern? oder habe ich hier etwas sehr wichtiges verpasst, das aufspringen und mich beißen und noch mehr trauern wird?
quelle
int
in 4255 Tagen (11,5 Jahren) erschöpfen . Wenn er das tun würde, würde er dich nur in 11,5 Jahren beschuldigen;)Antworten:
Sie müssen sich auf keinen Fall auf der GUID zusammenschließen. Wenn Sie über etwas verfügen, mit dem Sie andere Datensätze als diese GUID eindeutig identifizieren können , empfehlen wir Ihnen, einen eindeutigen Index für dieses andere Feld zu erstellen und diesen Index zu einem Cluster zu machen. Andernfalls können Sie auch mithilfe nicht eindeutiger Indizes Cluster für andere Felder erstellen. Der Ansatz, Cluster zu bilden, ist der beste, um Ihre Daten aufzuteilen und abzufragen. Wenn Sie also ein Gebietsfeld oder etwas anderes haben, ist dies möglicherweise ein Kandidat für Ihr Clustering-Schema.
Das Problem beim Wechsel zu a
BIGINT
wäre, Daten aus anderen Datenbanken zu ergänzen und deren Datenbank in den zentralen Speicher zu integrieren. Wenn dies keine Überlegung ist - und niemals eine Überlegung sein wird -, dannBIGINT
würde das das Problem der Indexanpassung gut lösen.Wenn Sie hinter den Kulissen keinen Clustered-Index angeben, geht SQL Server ähnlich vor: Es erstellt ein Zeilen-ID-Feld und ordnet alle anderen Indizes diesem zu. Wenn Sie es also selbst tun, lösen Sie es so, wie SQL es lösen würde.
quelle
Das ist eine große Aufgabe.
Lassen Sie mich einen Mittelmannansatz vorschlagen.
Ich hatte Probleme mit System.Guid.NewGuid (), das zufällige Guids generiert. (Ich habe dem Client erlaubt, eine eigene Guid zu erstellen, anstatt mich auf die Datenbank zu verlassen, um eine sequenzielle ID zu erstellen.)
Nachdem ich auf der Clientseite zu einem UuidCreateSequential gewechselt war, wurde meine Leistung VIEL besser, insbesondere bei INSERTs.
Hier ist der DotNet-Client-Code voodoo. Ich bin sicher, ich habe von irgendwoher verpfändet:
ABWECHSELNDE IDEE:
Wenn Ihre Hauptdatenbank und Ihre Remote-Datenbank "verknüpft" sind (wie in "sp_linkserver"), können Sie die Hauptdatenbank als "UUID-Generator" verwenden.
Du willst nicht "eins nach dem anderen" von uuid bekommen, das ist zu viel Geschwätz.
Aber du könntest dir ein paar UUIDs schnappen.
Unten ist ein Code:
/ *
* /
quelle
Gehen Sie gemäß Ihrer Beschreibung zu BIGINT. Der Index für GUID kann jedoch nicht eindeutig sein, da GUIDs ohnehin global eindeutig sein sollen.
quelle
Wenn GUID korrekt als uniqueidentifier gespeichert ist, sollte es keine Performance-Probleme geben ... und wenn Sie Sequential GUID noch besser nutzen können ...
Auch @mattytommo hat einen guten Punkt über 11,5 Jahre mit der Verwendung von INT ...
quelle