none
Brauche Brainstorming: 42 Mio Daten in eine Tabelle einfügen RRS feed

  • Frage

  • Hallo Leute,

    ich brauche mal ein paar Ideen.

    Ich habe eine Tabelle mit z.Zt. ca. 42 Mio. Datensätzen. Diese muß ich in eine andere Tabelle einfügen. Leider haut's mir das Log voll.

    Ich hätte nur die Idee, das in Schritten zu 1 Mio. DS zu machen. In dem Fall müßte ich aber mit Join o.ä. sicherstellen, daß nur die Sätze reinkommen, die noch nicht drin sind.

    Tabellenstruktur:

    CREATE TABLE [data].[PIP_BalanceSheetItems](
    	[AsAtDate] [datetime] NOT NULL,
    	[SourceSystemID] [varchar](10) NOT NULL,
    	[BPBILID] [varchar](16) NOT NULL,
    	[BPARTSNR] [varchar](5) NOT NULL,
    	[BPOSWERT] [decimal](20, 1) NULL,
    	[MASEINID] [varchar](5) NULL,
    	[AKMSEHTS] [varchar](4) NULL,
    	[SKLPTZWE] [decimal](4, 0) NULL,
    	[BPEURWRT] [decimal](19, 2) NULL,
     CONSTRAINT [PK_PIP_BalanceSheetItems] PRIMARY KEY CLUSTERED 
    (
    	[SourceSystemID] ASC,
    	[AsAtDate] ASC,
    	[BPBILID] ASC,
    	[BPARTSNR] ASC
    )ON [PRIMARY]
    ) ON [PRIMARY]

    Die Zieltabelle sieht genauso aus, nur die Feldnamen sind anders.

    Das Copy-Statement sieht so aus:

    		INSERT INTO data.BalanceSheetItems_PREP
        (
    		  AsAtDate
    		, SourceSystemID
    		, BalanceSheetID
    		, BalanceSheetItemID
    		, BalanceSheetItemValue
    		, BalanceSheetItemDimensionLev1
    		, BalanceSheetItemDimensionLev2
    		, BalanceSheetItemScalar
    		, BalanceSheetItemValueTeur
        )
    	SELECT
    		   AsAtDate
    		, SourceSystemID
    		, BPBILID
    		, BPARTSNR
    		, BPOSWERT
    		, MASEINID
    		, AKMSEHTS
    		, SKLPTZWE
    		, BPEURWRT
    			
    	FROM data.PIP_BalanceSheetItems 
        WHERE	AsAtDate		= @lAsAtDate
    	AND		SourceSystemID	= @lSystemID

    Würde mir hier ein Einfügen in Schritten was bringen, besonders in Bezug auf das LOG? Ich müßte die Zieltabelle ja als join oder in einer Where-Bedingung mit NOT EXISTS einbauen, was das LOG ja auch wieder belastet.

    Es kommt dann noch ein weiterer Schritt, wo die Daten mit ein bißchen Aufbereitung in eine weitere Tabelle geschrieben werden. Da hätte ich im Prinzip das Problem nochmal.

    Plattenplatz erweitern ist keine Option ;-)

    Gruß

    Christa

    Donnerstag, 29. März 2012 06:56

Alle Antworten

  • Hi,

    kannst du die Datensätze nicht über einen BULK Insert in die Tabelle einfügen und die Wiederherstellungoption der Datenbank vorher auf BULK INSERT stellen?

    Anschließend die Wiederherstellungsoption wieder auf FULL stellen und ein Vollbackup durchführen um die Datensicherung aktuell zu haben.

    Dann solltest du jedenfalls kein Problem mit dem Log haben oder?

    Grüße

    Oliver

    Donnerstag, 29. März 2012 07:03
  • Wie meinst Du "mit Bulk insert"?

    Das Wiederherstellungsmodell steht schon auf simple.

    Donnerstag, 29. März 2012 07:06
  • Hi,

    dann versuch einmal dein SQL Statement nicht mit einem "normalen" Insert durchzuführen, sondern mit BULK INSERT.

    Die genaue beschreibung findest du hier: http://msdn.microsoft.com/de-de/library/ms188365.aspx

    Dann sollte sich dein Log nicht mehr so aufblähen.

    Grüße

    Oliver

    Donnerstag, 29. März 2012 07:15
  • Hallo Christa,
    kannst Du nicht mit Select TOP(n) mit Order by Primary Key arbeiten?
    Dann holst Du Dir den maximalen Wert für die Primary Key Felder aus der Zieltabelle, in die Du eben eingefügt hast und beim nächsten Durchlauf hast Du ein
    Select Top (n) *
    from Tabelle
    where PK-Felder > maximaler Wert
    Order by PK-Felder;

    Nach jedem Durchgang könnte man prüfen, ob die @@Rowcount einigermaßen im gewünschten Bereich liegt und anschließend das (n) variieren.

    Falls die Zieltabelle bereits Daten enthalten hat, musst Du Dir eben auf anderem Wege den maximalen PK ermitteln, den Du eingefügt hast oder einfügen würdest.
    Man könnte z. B. mit der Row_Number über den Primary Key arbeiten und sich entsprechende Schritte ermitteln und merken, oder Du hast eine Vorstellung davon, wie Du die Daten aufteilen könntest, da in den PK-Feldern irgendwelche Nummernkreise verborgen sind.

    Aber auch die Aufteilung in Schritte bringt nur etwas, wenn Du häufig genug eine Logsicherung hinbekommst und dafür auch genügend Platz zur Verfügung steht.
     Eine andere Alternative könnte das Trace Flag 610 sein.
    http://www.insidesql.org/blogs/cmu/sql_server/trace-flag-610
    Kurfassung: Das Logging ist minimal, dafür werden beim Commit die Datenseiten geschrieben und nicht das Log. Das wird wahrscheinlich langsamer sein.
     Einen schönen Tag noch,
    Christoph
    --
    Microsoft SQL Server MVP
    www.insidesql.org/blogs/cmu

    Donnerstag, 29. März 2012 07:21
  • Hallo Christoph,

    ja, der Schlüssel wäre zum aufteilen der Daten geeignet. Ich müßte nur eruieren, wie das am sinnvollsten ist.

    Ich befürchte nur, daß ich damit zwar das LOG weniger belaste, dafür aber die tempdb stärker. Leider leigen alle Datenbanken auf den gleichen Platte (ich weiß, das ist nicht optimal, aber da habe ich keinen Einfluß drauf).
    Ich brauche eine Lösung, bei der ich nicht ein Problem gegen ein anderes eintausche.

    Vielleicht erledigt sich das Problem aber gerade, weil ev. die Datenmenge noch drastisch eingeschränkt werden kann. Da sind wir am Verhandeln.

    @Oliver

    Ich kopiere von einer SQL Server Tabelle in eine andere, nicht aus einem File. Außer select into wüßte ich keine Bulk-Methode, die da ginge. Und das steht nicht zur Debatte.

    Donnerstag, 29. März 2012 07:42
  • Hallo Christa,
    wenn du einen Primary Key mit Index hast, sollte die tempdb nicht so sehr darunter leiden.
     Einen schönen Tag noch,
    Christoph
    --
    Microsoft SQL Server MVP
    www.insidesql.org/blogs/cmu

    Donnerstag, 29. März 2012 07:58
  • Hallo Christa,

    sorry hatte ich irgendwie überlesen :-)

    Und wenn du eine neue Spalte vom Typ Timestamp zur Ursprungstabelle hinzufügst. In diese könntest du einen berechnetetn Wert (CAST(AsAtDate)) einfügen.

    Somit hättest du einen Wert nach dem du sortieren und abfragen könntest.

    Grüße

    Oliver

    Donnerstag, 29. März 2012 08:16