0

Ich fragte eine question, die war, wie kann ich eine Aufgabe schneller ausführen, aber keine der Antworten funktionierte für mich. Ich habe den folgenden Code, der 1500 Datensätze in die Datenbank einfügt, aber das Problem ist, dauert es etwa 4 Sekunden. Ich verwendete async/await, parallele Schleife und AddRange und auch ich deaktivierte Änderung automatische Erkennung und Validierung beim Speichern, aber keiner von ihnen hat Wirkung. Mein Code ist dies:Einen Eintrag zur Datenbankaufgabe schneller ausführen

async void button7_Click(object sender, EventArgs e) 
{ 
    var task = await Task.Run(() => 
    { 
     Random rnd = new Random(); 
     for (int i = 0; i <= 1500; i++) 
     { 
      db.Tbls.Add(new Tbl() 
      { 
       Name = "User" + i + 1, 
       Num = rnd.Next(10, i + 10)/10 
      }); 
     } 

     db.SaveChanges(); 
     return db.Tbls.Count(); 

    }); 
} 

Und mit AddRange:

async void button7_Click(object sender, EventArgs e) 
{ 
    var task = await Task.Run(() => 
    { 
     Random rnd = new Random(); 
     var tbls = new List<Tbl>(); 
     for (int i = 0; i <= 1500; i++) 
     { 
      tbls.Add(new Tbl() 
      { 
       Name = "User" + i + 1, 
       Num = rnd.Next(10, i + 10)/10 
      }); 
      progress.Report(i * 100/1500); 
     } 
     db.Tbls.AddRange(tbls); 
     db.SaveChanges(); 
     return db.Tbls.Count(); 

    }); 
} 

Und mit paralleler Schleife:

var task = await Task.Run(() => 
{ 
    int seed = Environment.TickCount; 
    var random = new ThreadLocal<Random>(() => new Random(Interlocked.Increment(ref seed))); 
    var tbls = new ConcurrentBag<Tbl>(); 
    Parallel.For(0, 1500, (i) => { 
     tbls.Add(new Tbl() 
     { 
      Name = "User" + i + 1, 
      Num = random.Value.Next(10, i + 10)/10 
     }); 
    });     
    db.Tbls.AddRange(tbls); 
    db.SaveChanges(); 
    return db.Tbls.Count(); 
}); 

Weiß jemand, was ist das Problem?

+2

Hat Ihr Tisch einen Primärschlüssel? Wieviel Zeit braucht man, um 1500 Datensätze ohne asynchrone und/oder parallele Ausführung einzufügen? Wenn Sie sich die SQL Profiler-Ausgabe ansehen, welche "unsichtbaren" Operationen außer den "Einfügen" -Befehlen sehen Sie dort? – Arvo

+0

Ja. Mein Tisch hat einen Primärschlüssel. Mit oder ohne asynchrone und/oder parallele Ausführung dauert es ca. 4 Sekunden. Ich habe auch Code First Approach verwendet. –

+0

In diesen Snippets ist kein Zugriff auf die parallele Datenbank möglich. Alle diese Snippets machen genau dasselbe - rufen Sie 'SaveChanges' synchron auf. –

Antwort

1

Wenn Sie eine signifikante Anzahl von Zeilen in einem Treffer in die Datenbank laden möchten, erhalten Sie wahrscheinlich eine bessere Leistung beim Massenladen. Ich könnte mir vorstellen, dass 1500 Einfügungen ganz einfach 4 Sekunden dauern, wenn Sie einzelne Zeilen laden - und Sie werden wahrscheinlich keine einzelnen Einfügungen schneller ausführen, da der Hauptengpass die minimale I/O ist, die für eine Datenbanktransaktion benötigt wird.

Mit einer Massenlast-API - z.B. SQLBulkCopy - Sie bereiten einen Datensatz vor und laden ihn dann mit einem Treffer in die Datenbank. Dies wird viel, viel schneller als 1.500 einzelne Einsätze sein.

Sie haben nicht die DB-Plattform angegeben, für die Sie einen Treiber benötigen, der das Laden von Massen unterstützt. Der SQL Server tut dies; einige (zum Beispiel) die Oracle-Versionen funktionieren nur, wenn Sie bestimmte Editionen kaufen.

+0

Ich benutze SQL Server. Ich bin mir sicher, dass mein Code mindestens eine Sekunde lang laufen sollte. Aber ich weiß nicht warum und was ist das Problem, das dazu geführt hat, dass es zu lange dauert. –

+0

Können Sie mir bitte ein Beispiel im Entitätsrahmen zeigen? –

+0

OTOH Ich weiß nicht, ob Entity-Framework das Laden von Massen unterstützt. Möglicherweise müssen Sie die SQLBulkCopy-API direkt verwenden. – ConcernedOfTunbridgeWells

Verwandte Themen