Beste path, um eine nächtliche dataübertragung zu programmieren, Identitätsspalte läuft hoch

Ich schreibe eine Anwendung, die jede eigene database mit einer anderen database synchronisieren muss. Wenn die data gezogen werden, wird sie auch in einer komplexen Weise programmatisch umgesetzt.

Jetzt sehe ich zwei mögliche Ansätze:

  • Methode A: jede Nacht lösche ich alle zuvor importierten Zeilen, und mache einen vollständigen Reimport, diese Methode ist teuer, aber einfach zu programmieren, zu pflegen, insgesamt robust

  • Methode B: Ich speichere einen Verweis auf die ursprünglichen data für jede importierte Zeile und mache eine Einfügung, Aktualisierung oder Löschung, wenn die data jeweils neu sind, geändert oder entfernt werden (wobei die reference allein sehr komplex ist, da es keine einfache Eins-zu- -einige Beziehung)

Eindeutig ist Methode B komplizierter und könnte leichter zu Bugs führen, also bevorzuge ich die Methode A. Jedoch, da etwa 100.000 Zeilen jede Nacht eingefügt werden, läuft die Identitätsspalte im Laufe der time sehr hoch. Ein einfaches Zurücksetzen auf 1 jede Nacht ist keine Option, da die eingeführten Zeilen tatsächlich mit anderen Zeilen gemischt werden, die nichts mit der dataübertragung zu tun haben, diese letzten Satzreihen müssen von der Übertragung nicht beeinflusst werden.

Die wichtigste Frage, die ich darüber habe, ist, ob es überhaupt ein Problem ist, dass unsere Identitätsspalte hoch läuft (jährlich etwa 36 Millionen). Es ist nicht ordentlich, aber wird es schließlich ein Performance-Hit, und was wird passieren, wenn wir jemals erreichen die maximale int Wert? Hat jemand ähnliche Herausforderungen gestellt und kann ihre Erfahrungen teilen?

wird dort schließlich ein Performance-Hit sein

Ich verstehe nicht, warum es sein sollte. Die Größe des Feldes ist gleich (zB 32 Bit), also werden alle Operationen mit derselben Geschwindigkeit durchgeführt, ob der Wert des Feldes 10 oder 2.000.000.000 beträgt.

Wenn Ihre Identitätsspalte int (32 Bit) ist, dann 2,147,483,647 / 36,000,000 = 59 es für 2,147,483,647 / 36,000,000 = 59 Jahre.

Es ist sehr einfach zu überprüfen, was passieren würde, wenn man das Maximum erreicht 2,147,483,647. Erstellen Sie eine Tabelle in tempdb. (Ich benutze SQL server 2008 für diesen Test).

 USE [tempdb] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[BigTable]( [ID] [int] IDENTITY(1,1) NOT NULL, [Data] [int] NOT NULL, CONSTRAINT [PK_BigTable] PRIMARY KEY CLUSTERED ( [ID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO 

Identität auf hohen Wert setzen:

 USE [tempdb] GO DBCC CHECKIDENT ("[dbo].[BigTable]", RESEED, 2147483645); 

Versuche, 10 Zeilen einzufügen:

 USE [tempdb] GO INSERT INTO [dbo].[BigTable] ([Data]) VALUES (0) GO 10 

Das bekomme ich im Ausgabefenster:

 Beginning execution loop (1 row(s) affected) (1 row(s) affected) (1 row(s) affected) Msg 8115, Level 16, State 1, Line 2 Arithmetic overflow error converting IDENTITY to data type int. Arithmetic overflow occurred. ** An error was encountered during execution of batch. Continuing. Msg 8115, Level 16, State 1, Line 2 Arithmetic overflow error converting IDENTITY to data type int. Arithmetic overflow occurred. ** An error was encountered during execution of batch. Continuing. Msg 8115, Level 16, State 1, Line 2 Arithmetic overflow error converting IDENTITY to data type int. Arithmetic overflow occurred. ** An error was encountered during execution of batch. Continuing. Msg 8115, Level 16, State 1, Line 2 Arithmetic overflow error converting IDENTITY to data type int. Arithmetic overflow occurred. ** An error was encountered during execution of batch. Continuing. Msg 8115, Level 16, State 1, Line 2 Arithmetic overflow error converting IDENTITY to data type int. Arithmetic overflow occurred. ** An error was encountered during execution of batch. Continuing. Msg 8115, Level 16, State 1, Line 2 Arithmetic overflow error converting IDENTITY to data type int. Arithmetic overflow occurred. ** An error was encountered during execution of batch. Continuing. Msg 8115, Level 16, State 1, Line 2 Arithmetic overflow error converting IDENTITY to data type int. Arithmetic overflow occurred. ** An error was encountered during execution of batch. Continuing. Batch execution completed 10 times. 

Dies ist das Ergebnis:

 USE [tempdb] GO SELECT [ID] ,[Data] FROM [dbo].[BigTable] GO ID Data 2147483645 0 2147483646 0 2147483647 0 DBCC CHECKIDENT ("[tempdb].[dbo].[BigTable]", NORESEED); Checking identity information: current identity value '2147483647', current column value '2147483647'. DBCC execution completed. If DBCC printed error messages, contact your system administrator. 

Also, ja es gibt Probleme, wenn du alle int-Werte ausschöpft. Du kannst stattdessen bigint benutzen. Es ist 64-Bit (8 Bytes, nicht 16) und wird viel viel länger 9,223,372,036,854,775,807 / 36,000,000 = 256,204,778,801 : 9,223,372,036,854,775,807 / 36,000,000 = 256,204,778,801 Jahre Die Performance von bigint ist so ziemlich das gleiche wie int auf 64-Bit-Computern. Es kann langsamer sein als int, nur weil es doppelt so groß ist und der server muss zweimal die Anzahl der Bytes auf die Festplatte lesen und schreiben und doppelt so viel memory verwenden.

In Bezug auf die performance, was wirklich wichtig ist, ist, dass Sie Indizes neu erstellen und Statistiken auf Ihrem Tisch aktualisieren, nachdem Sie viele Zeilen gelöscht und eine Menge Zeilen hinzugefügt haben, da alle Statistiken stark schief sind. Hier meine ich die performance des restlichen Systems, die diese Tabelle verwenden würde, nicht den Vorgang zum Löschen und Hinzufügen von Zeilen.

Um die performance des nächtlichen Synchronisierungsprozesses zu verbessern, der viele Zeilen löscht und viele Zeilen hinzufügt, ist es wichtig, alle Indizes auf der Tabelle zu deaktivieren, bevor die Änderungen und die Wiederherstellung nach den Änderungen wiederhergestellt werden.

Du wirst so lange handeln, wie deine Identität ein 64-Bit-Int oder besser ist. Es ist nicht ideal, aber es wird für ein paar Jahre arbeiten, bis Sie entscheiden, dass Sie wirklich brauchen, um wirklich Reflektor.

Ja, du könntest eine ideale Lösung build, aber es klingt, als müsstest du jetzt eine "gut genug" Lösung? Was ist das, was Methode A ist.