Frage

Unsere App benötigen große Mengen an Text zu SQL Server 2005-Datenbank hinzuzufügen (bis zu 1 GB für einen einzelnen Datensatz). Aus Performance-Gründen ist dies in Blöcken erfolgt durch Aufruf einer gespeicherten Prozedur für jeden Chunk machen (sagen wir, usp_AddChunk). usp_AddChunk keine expliziten Transaktionen hat.

Was ich sehe, ist, dass in massiv größeren Transaktionsprotokollen die Blockgröße von 100 MB bis 10 MB Ergebnisse zu reduzieren. Ich habe gesagt, dies liegt daran, dass jedes Mal, usp_AddChunk genannt wird, eine „implizite“ (mein Ausdruck) Transaktion wird alle bestehenden Text protokolliert. Also, für einen 150 MB Rekord:

100MB Chunkgröße: 100 (0 Bytes angemeldet) + 50 (100 MB angemeldet) = 100 MB angemeldet

wird kleiner sein als

10 MB Chunkgröße: 10 (0 Bytes angemeldet) + 10 (10 MB angemeldet) + 10 (20 MB angemeldet) ... + 10 (140 MB angemeldet) = 1050 MB protokollierten

Ich dachte, dass durch eine Transaktion in meinem C # -Code zu öffnen, diese „implizite“ Transaktion nicht passieren würde (bevor ich die ersten Brocken, und begehen nach dem letzten Brocken hinzufügen), und ich konnte die riesigen Log-Dateien vermeiden. Aber meine Tests zeigen, das Transaktionsprotokoll 5x immer größer die ADO.NET-Transaktion.

Ich werde den Code nicht veröffentlichen, aber hier ein paar Details:

  1. Ich nenne SqlConnection.BeginTransaction ()
  2. Ich verwende eine andere SqlCommand für jeden Chunk
  3. I ordnen die SqlTransaction von (1) zu jedem SqlCommand
  4. I in der Regel die Verbindung nach jeder SqlCommand Ausführung schließen, aber ich habe auch versucht, die Verbindung mit den gleichen Ergebnissen nicht schließen

Was ist der Fehler in diesem System? Lassen Sie mich wissen, wenn Sie weitere Informationen benötigen. Dank!

Hinweis: ein einfaches oder Bulk-Protokollierung unter Verwendung von Wiederherstellungsmodell ist keine Option

War es hilfreich?

Lösung

Wenn von 'Brocken' meinen Sie so etwas wie:

UPDATE table
SET blob = blob + @chunk
WHERE key = @key;

Dann sind Sie richtig, dass der Betrieb vollständig protokolliert. Sie sollten die BLOB Nutzungsrichtlinien und Nutzung folgen die .Write Methoden für chuncked Updates:

UPDATE table
SET blob.Write(@chunk, NULL, NULL)
WHERE key = @key;

Dies wird minimal das Update log (wenn möglich, siehe Operationen das sein kann minimal protokollierte ):

  

Die UPDATE-Anweisung wird vollständig protokolliert;   jedoch teilweise Updates zu groß   Wert-Datentypen der .WRITE mit   Klausel ist minimal protokolliert.

Nicht nur, dass diese minimal protokolliert wird, sondern weil das Update am Ende des BLOB eine explizite Schreib ist, wird der Motor, dass Sie nur einen Teil des BLOB aktualisiert und wird nur log , die . Wenn Sie mit SET blob=blob+@chunk te Motor aktualisiert werden sehen, dass die gesamte BLOB einen neuen Wert erhalten hat und wird die Tatsache nicht erkennen, dass Sie wirklich nur die BLOB geändert durch neue Daten angehängt, so dass die sie das gesamte BLOB (mehrmals einzuloggen, wie Sie bereits herausgefunden).

BTW sollten Sie Brocken Größe Vielfaches von 8040 verwenden:

  

Für eine optimale Leistung empfehlen wir,   daß Daten eingefügt oder aktualisiert werden, in   Blockgrößen, die ein Vielfaches von 8040 sind   Bytes.

Andere Tipps

Was können Sie tun müssen, ist jedes „Brocken“ umgeben oder eine Gruppe von Stücken mit einer eigenen Transaktion und nach jeder Gruppe begehen. Rund um die ganze Sache mit Ihrem eigenen ADO-Transaktion wird die gleiche Sache im Wesentlichen tun, wie die implizite Transaktion der Fall ist, so dass nicht helfen. Sie haben in kleinere Stücke zu begehen das Protokoll kleiner zu halten.

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