none
Performance beim CSV Import in SQL Datenbank RRS feed

  • Frage

  • Hallo Group,

    hat jemand eine Idee wie ich effektiv etwas an der Performance beim Import einer CSV Datei in eine SQL Datenbank verbessern kann?
    Aktuell komme ich auf 10 Sätze/Sekunde, das bedeutet bei 300.000 Datensätzen 8 Stunden für den Import!

    Bei der Azure SQL Datenbank wechselte ich bereits von Basic auf Standard.

    Das Tool nutzt Entity Framework 6 mit Linq.
    Ich weiß, dass Linq-Abfragen nicht unbeding performant sind, deshalb löse ich den Import mit einer Stored Procedure.
    Die Idee ist, dass dadurch auf dem Server der eigentliche Job ausgeführt wird und keine Objekte zum Client übertragen werden müssen. Das hat auch was gebracht.

    Der Code für dem Import ist dadurch auf ein Dreizeiler geschrumpft (Rest ist für die Progressbar):

    For Each itmRow As DataRow In dtFields.Rows
     
             rowRemaining += 1
             mainForm.setProgress(CType(((rowRemaining) / rowCounts) * 100, Integer)) 'Fortschritt in %: Mit Dreisatz
    
             dbContext.ImportMaterial(itmRow.Item("ean"), itmRow.Item("mnr"), itmRow.Item("ktxt"), itmRow.Item("me"), itmRow.Item("quelle"), 1, 0, 1, Now, My.Settings.User, Now, My.Settings.User)
    
    Next


    Hier ein Ausschnitt aus der Stored Procedure:

    BEGIN
    UPDATE DTA_MATERIAL         SET ean=@ean, matnr=@matnr, [description]=@description, packing_unit=@packing_unit, [source]=@source, unit_of_price=@unit_of_price, price=@price, stock=@stock, create_date=@create_date, create_user=@create_user, update_date=@update_date, update_user=@update_user         WHERE matnr=@matnrIF @@ROWCOUNT = 0     BEGIN         INSERT INTO DTA_MATERIAL (ean,matnr,[description],packing_unit,[source],unit_of_price,price,stock,create_date,create_user,update_date,update_user)         SELECT @ean, @matnr, @description, @packing_unit, @source, @unit_of_price, @price, @stock, @create_date, @create_user, @update_date, @update_user     END END

    Der Primary Key ist auf der matnr.

    Die Internetverbindung hatte ich nicht gemessen. Wird wohl irgendwo zwischen 10 und 13 Mbit/s (Down) und 1,5 Mbit/s (Up) gewesen sein.

    Kann man bei diesen Rahmenbedingungen noch was rausholen?

    Gruß Achim



    • Bearbeitet iwrschenk Samstag, 20. Oktober 2018 14:29
    Samstag, 20. Oktober 2018 14:28

Alle Antworten

  • Hallo Achim,
    der Hauptgrund sollte EF sein. Hier werden deine Daten Zeilenweise übertragen.
    Wenn das so möglich ist stell auf Mengenverarbeitung um.

    1. Übertrage deine Rohdaten in eine Temporäre Tabelle via Bulk Insert.
    Hier ein Link der auch Performance mit diversen Ansätzen vergleicht und den Weg aufzeigt:
    https://stackoverflow.com/questions/5940225/fastest-way-of-inserting-in-entity-framework

    2. Verarbeite komplett auf dem SQL Server aus der Temporären Tabelle in dein Ziel.
    Aber dort nicht Zeilenweise sondern Mengenbasiert.
    Ein Weg wäre den Merge zu nutzen. 
    Hier ein Beispiel: https://docs.microsoft.com/de-de/sql/t-sql/statements/merge-transact-sql?view=sql-server-2017

    HTH
    Grüße Alexander

    Montag, 22. Oktober 2018 16:42
  • Danke, hört sich gut an.

    Dem werde ich mal nachgehen.

    Gruß Achim

    Dienstag, 23. Oktober 2018 14:54