Frage

Ich möchte Tabellen auf die bestmögliche Art und Weise tauschen.
Ich habe eine IpToCountry Tisch, und ich eine neue erstellen auf wöchentlicher Basis gemäß einem externen CSV-Datei, die ich importieren.

Der schnellste Weg, die ich gefunden habe den Schalter machen werden Sie folgendermaßen vorgehen:

sp_rename IpToCountry IpToCountryOld
go
sp_rename IpToCountryNew IpToCountry
go

Das Problem dabei ist, dass der Tisch zwischen könnte noch zugegriffen in.
Wie nähere ich dieses Problem in SQL?
In Betracht gezogen sp_getapplock und sp_releaseapplock, aber ich möchte so schnell wie möglich die Lese von der Tabellenfunktion zu halten.

War es hilfreich?

Lösung

Unter der Annahme, dass Sie nicht in der Lage sind, in die vorhandenen Tabelle aktualisieren / einfügen, warum Sie alle Zugriff auf die Tabelle nicht wickeln Sie ein Ansicht ?

Zum Beispiel könnten Sie zunächst speichern Sie Ihre Daten in einer Tabelle mit dem Namen IpToCountry20090303 , und Ihre Sicht wäre so etwas wie dies:

CREATE VIEW IpToCountry
AS
SELECT * FROM IpToCountry20090303

Wenn die neuen Daten in kommt, können Sie erstellen und füllen Sie die IpToCountry20090310 Tabelle. Sobald die Tabelle ausgefüllt ist nur aktualisieren Sie Ihre Ansicht:

ALTER VIEW IpToCountry
AS
SELECT * FROM IpToCountry20090310

Der Schalter wird vollständig atomar sein, ohne eine explizite Sperre oder Transaktionen zu erfordern. Sobald die Ansicht aktualisiert wurde, können Sie einfach die alte Tabelle löschen (oder es halten, wenn Sie bevorzugen).

Andere Tipps

Ein andere Methode zu implementieren, was Sie suchen die Verwendung von Tabellenpartitionierung zu erreichen wäre, eine Technik, die in der Enterprise Edition von SQL Server verfügbar ist.

Der Tabellenname kann gleich bleiben. Nachdem Sie Ihre Tabelle Import abgeschlossen ist, schalten Sie aus Sie einfach nur die Partition Ihre alten Daten und Schalter in der neuen Partition enthält.

Die folgenden White Paper enthalten alle Informationen, die Sie beginnen müßten.

http://msdn.microsoft.com/en-us/library /ms345146.aspx

Cheers, John

Ich habe Probleme bekommen Partitionierungsfunktionen habe im großen Maßstab zu arbeiten. CREATE und DROP PARTITION sind blockiert Operationen, und Sie haben wenig Kontrolle über die Sperrung, und wenn es keine Sperre wird es nicht mit einem Schweregrad 16 und töten Sie Ihre Verbindung bekommen - was kann man nicht fangen und erneut versuchen, ohne die Wiederherstellung die Verbindung. Aber es könnte für Sie gut funktionieren. Auch MSS Enterprise Edition erforderlich ist, können Sie nicht SE verwenden - vielleicht zu viel für einige kleinere oder kosten betroffenen Geschäften.

Ich habe auch festgestellt, die Ansicht REDEF bei hohen Maßstab zu blockieren (= Transaktionsvolumen + schiere Menge der ständig eingefügten Daten, in meinem Fall) auf sys Tabellen und Objekte, so können diese Vorgänge auf die Dinge Deadlock wie reindexing und DTCCs - und in einem Fall, und zwar mit einem Benutzer in SSMS (alle Dinge) versuchen Ansichten im Objekt-Explorer durchsuchen (jemand muss den Jungs über READPAST sagen). Auch hier können Sie Ihre Laufleistung variieren.

Im Gegensatz dazu arbeitet die sp_rename gut für mich in großem Maßstab: es gibt Ihnen die Verriegelungs Kontrolle über und den Umfang davon. Um die Blockierung Problem zu lösen vor dem Swap, versuchen Sie es wie unten gezeigt. Auf dem ersten Blick würde dies scheint das gleiche Maßstab Problem bei hohen Lautstärke zu haben ... aber ich habe es in der Praxis nicht gesehen. So funktioniert für mich ... aber auch hier jedermanns Bedürfnisse und Erfahrungen sind unterschiedlich.

DECLARE @dummylock bit 
BEGIN TRANSACTION 
BEGIN TRY
   -- necessary to obtain exclusive lock on the table prior to swapping
   SELECT @dummylock = 1 WHERE EXISTS (SELECT 1 FROM A WITH (TABLOCKX))
   -- may or may not be necessary in your case
   SELECT @dummylock = 1 WHERE EXISTS (SELECT 1 FROM B WITH (TABLOCKX))
   exec sp_rename 'A', 'TEMP'
   exec sp_rename 'B', 'A'
   exec sp_rename 'TEMP', 'B'
   COMMIT TRANSACTION
END TRY
BEGIN CATCH
   -- other error handling here if needed
   ROLLBACK TRANSACTION 
END CATCH

Was passiert mit IpToCountryOld? Werfen Sie es Haben Sie weg? In diesem Fall, warum nicht IpToCountry gestutzt und meine neue Daten importieren.

Wenn Sie die Daten zu halten, wie etwa die Belastung Datum auf dem Tisch Speicher und Speicher den „aktuellen“ Last Zeitpunkt irgendwo in einer WHERE-Klausel verwendet werden? Dann schalten Sie das aktuelle Datum, wenn die Daten erfolgreich geladen.

Sie sagen nicht, dass die DB Sie verwenden, so dass ich weiß nicht, wie viel Einsatz das ist, aber Sie haben keine gespeicherten Prozeduren, die die Tabelle verweisen? Seien Sie gewarnt, dass SPs auf einigen Plattformen sind interne Verweise auf Tabellen zusammengefasst verwenden, die nicht mit einem Umbenennungs ändern, so dass es ein Risiko, dass SPs werden Ihre neuen Daten ohne erneute Kompilierung abholen. Das gleiche gilt für Views und Stored analysiert Abfragen wahr sein.

Können Sie nicht tun, um den Import der einen Tisch außerhalb der Geschäftszeiten?

Oder warum nicht nur eine Aktualisierung der Daten tun, das heißt, die vorhandenen Datensätze aktualisieren und fügen Sie alle neuen auf einem datensatzweise, wie Sie Schleife, um die Daten zu importieren. Dies würde es ermöglichen die Tabelle zu Hause zu bleiben und die Gesamtauswirkungen der Add- und Drop-Voll Tabellen zu reduzieren.

Was ist die Struktur der Daten importiert, Tisch Design, Format, PK, etc? Von dass wir möglicherweise in der Lage sein, Ihnen eine bessere Antwort zu geben.

lief in ein ähnliches Problem auf einer Staging-Tabelle arbeiten, die Probleme mit dem richtigen Schlössern Skalierung hatte.

überall Ihre Tabelle referenziert Sie eine gespeicherte Prozedur zu fragen für die Tabellennamen nennen könnten.

Die gespeicherte Prozedur würde die neue Tabelle (n) oder kehren die alten Tabellen optional erstellen, die auf die Parameter in Abhängigkeit zur Verfügung gestellt.

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