VB6, Ms-Access-Datenbank-Bearbeitung von großen Mengen an Akten
Brauche ich, um zu verarbeiten Hunderte oder Tausende von Datensätzen mit VB6 und MS Access-Datenbank. Ich Durchlaufen des Recordsets und Bearbeiten jedem Datensatz. Allerdings dauert es eine Menge Zeit, dies zu tun. Erstellen einer Datenbank mit der gleichen Menge der Datensätze mit der Addnew und Update-Methoden arbeitet viel schneller.
Ich werde sehr dankbar, wenn jemand mir zeigt, jede code-Beispiel oder nur eine Strategie.
Hier ist der code
Data1(1).RecordSource = "Select * from TABLE order by Field_A ASC"
Data1(1).Refresh
If Data1(1).Recordset.RecordCount > 0 Then
Data1(1).Recordset.MoveFirst
Do
Data1(1).Recordset.Edit
Data1(1).Recordset.Fields("FIELD") = Sort_Value
Data1(1).Recordset.Update
Data1(1).Recordset.MoveNext
Loop Until Data1(1).Recordset.EOF = True
End If
Es ist wirklich ganz ganz einfach. Die Reale Sache ist, ich habe vergessen zu erwähnen, dass tha HDD der computer ständig rot/schreibt. Dies ist tatsächlich das problem. Mit eine so schwere Last, dort ist keine Weise, nicht auf die Leistung auswirken.
Ich dachte zuerst, dass das recordset von der Abfrage generierte, im Hinterkopf behalten, dass wir hane 1-2 Millionen Datensätze, die das problem verursacht. Ich denke, es befindet sich auf einem temporären Platz auf der Festplatte und im RAM. Und so executin .Bearbeiten und .Update könnte ein problem in der ersten positionieren Sie den cursor an der richtigen Stelle und dann schreiben.
Weiß es nicht sicher. Wahrscheinlich würde es ein Experte sein, um mir zu zeigen, einen Weg aus.
Btw. Ich habe auch versucht mit dem Austausch der
Schleife, Bis Sie Data1(1).Recordset.EOF = True
Anweisung mit fester Länge-Zyklus, denn ich habe auch gelesen, dass diese überprüfung für die Recordset.EOF verlangsamt Leistung.
Vielen Dank im Voraus!
- teilen Sie Ihre code -, UPDATE-Anweisung etc. hilfreich
- Mithilfe einer Transaktion eher als das schreiben der updates jedes mal wird wesentlich schneller sein, siehe mein Beispiel Antwort hier: stackoverflow.com/questions/12930603/...
- Ich habe angefangen, ein Kopfgeld für Sie, da bin ich neugierig auf diese mir. Wenn Sie die Bearbeitung Ihrer post, die code enthalten, den Sie momentan verwenden, könnte es helfen, Menschen zu finden, die Ihren code auch für die Schwächen.
- Es ist wirklich schwer zu sagen, wie sollten Sie die Geschwindigkeit verbessern, was Sie tun, wenn Sie nicht zeigen (oder zumindest sagen) Sie uns, was Sie tun in den ersten Platz. "Wie kann ich meinen code schneller? Ich werde nicht, Sie Ihnen zu zeigen, oder sogar sagen, was es genau macht. Können Sie mir helfen?"
- Nur eine Frage; können Sie uns sagen, wenn die Tabelle über Indizes verfügt oder wichtige Felder, und, wenn ja, welche Felder sind das?
- +1 für die Verwendung einer Transaktion, da @MattDonnan schlägt. Die Testergebnisse here sind für Einsätze, aber eine Transaktion beschleunigen kann Chargen von updates zu.
- Anscheinend verwendest du ein Daten-Steuerelement mit DAO zu aktualisieren Sie Ihre Aufzeichnungen. Loswerden, dass Daten-Steuerelements und verwenden nur plain-Recordsets. Entfernen Sie auch die
Order By
wenn nicht benötigt. Wiederholen Sie dann den Vorgang. - BellyMark - Können Sie überprüfen, shareef Antwort und sehen, ob es beschleunigt den Prozess? wenn ja, bitte geben Sie ihm die Akzeptierte Antwort Haken, so kann ich die Auszeichnung der bounty. Wenn nicht, lassen Sie es uns bitte wissen. Danke!
- Ich habe das Gefühl, das wir nicht hören von ihm, bis er wieder an die Arbeit in ein paar Stunden. Sobald wir mehr details darüber, wo er die erste Sort_Value, desto besser können wir ihm helfen.
- Hallo, mal wieder!Sorry für die Unterbrechung, aber eine Sache hielt mich davon entfernt. Ich vergaß zwei wichtige Sache zu erwähnen:1. Die Indizierung wird nicht ganz für mich arbeiten, denn es gibt wirklich eine Menge von Daten, die dynamisch generiert, so dass, sobald ein Datensatz bearbeitet wird, ist es nur selten zurückkommen. 2. Mehr wichtig - ich entschuldige mich erneut vergessen zu erwähnen, ist, dass die Aufzeichnungen müssen Durchlaufen, da die Aufgabe ist zu berücksichtigen, die benachbarten Datensätze Werten.
- Sie können Sie aktualisieren, basierend auf der angrenzenden Rekord-Werte über eine Abfrage zu. Je nach Daten kann es erforderlich, eine Unterabfrage obwohl. Ich denke, es wäre es Wert für Sie zu post-ein Beispiel für die Daten und das Ergebnis, die Sie suchen.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Erstellte ich eine Tabelle namens
test
mit den Feldernn
undf(n)
Timed 3 verschiedene update-Unterprogramme
- recordset ohne Transaktion
- recordset mit der Transaktion
- update-Abfrage
Dies ist im Grunde, was Sie tun, eine gerade recordset während der Bearbeitung ein Feld
Dies ist die gleiche Idee, aber mit Transaktionen. Ich verpflichte 5000 Datensätze in einer Zeit, als es war einige Grenzwerte um 9k-10k pro commit. Sie können Bearbeiten das glaube ich, indem Sie in der registry.
Dies ist schneller als alle recordset-Methoden. E. g. auf rund 2 Millionen Datensätze dauerte es ~20 Sekunden ohne Transaktionen, ~18-19 Sekunden mit Transaktionen, ~14 Sekunden mit der update-Abfrage.
All dies ist unter der Annahme, dass das Feld aktualisiert werden, hängt von berechneten Werten aus anderen Unholde innerhalb dieser Datensätze
Wirklich beschleunigen diese Art von Aktionen, manchmal ist es abhängig von der situation und mehr detail ist erforderlich, wenn dies nicht gelten.
Edit: alten core 2 duo Rechner + keine Indizes auf die Felder
DBEngine.SetOption dbMaxLocksPerFile, 300000
im VBA-code, und dann könnte man erhöhen Sie IhrecommitSize
auf ~250.000 an.Meine einzige Anregung, die möglicherweise nicht in Ihrem Fall, zu tun, die die Masse-updates über eine update-Abfrage.
Drei Fälle, in denen das funktionieren könnte:
Wenn Sort_Value kann errechnet werden aus anderen Bereichen, das ist eine einfache UPDATE-Abfrage, aber ich bin sicher, Sie hätte das schon gesehen.
Wenn Sort_Value kann berechnet werden aus anderen Aufzeichnungen (wie vorheriger Eintrag), dann kann man wohl schreiben ein komplexer UPDATE-Abfrage (ich habe gesehen, einige ziemlich komplexe Abfragen hier gepostet).
Schließlich, wenn die gleichen Sort_Value angewendet wird, um eine Menge von Datensätzen, dann können Sie eine UPDATE-Abfrage basierend auf diesen Datensätzen. Also, wenn Sort_Value könnte sein, 10 verschiedene Werte, dann alle updates gemacht werden würde in 10 UPDATE-Abfragen.
Wenn Sie uns mitteilen, wo du die Sort_Value, wir könnten in der Lage sein, um Ihnen weiter helfen.
Hier einige Dinge, die NICHT Arbeit zu beschleunigen, können Sie den edit/update-Befehle, nach meiner Prüfung. Dies alles ist geschehen, mit einer Tabelle mit 10.000 Datensätzen, mit 1.000.000 updates.
tatsächlich erhöht die Zeit um 20%. (25 Sek. /21 Sek)
1% schneller auf einem indizierten Feld. (un-indiziert: 11 sec [w/trans] /
11 Sek., indiziert: 23 sec [w/trans] /25 Sek.) *
*Korrigierte Ergebnis.
Code für die BeginTrans/CommitTrans-test.
Zwar kann es in einigen Fällen erforderlich sein, das Durchlaufen von Datensatzgruppen, um ein Feld aktualisieren, sollten vermieden werden.
Die vernünftige Sache zu tun, die ist viel effektiver wäre es, schreiben Sie eine SQL update Abfrage.
Wenn Ihre Tabelle ist so groß, Sie müssen vorsichtig sein mit der Wahl Ihrer Indizes, speziell den primary key.
Dann, teilen Sie die Daten basierend auf Ihrer PK, und aktualisieren Sie alle Datensätze in den ersten Satz, dann im zweiten, Dritten...
Wiederholen Sie diese (durch code) für alle Bereiche, die Sie gemacht haben in Ihrer Tabelle.
Nun, die Frage ist - kannst du dir eine Access-Funktion, die erstellt die erforderlichen Sort_value?
Beachten Sie, dass, wenn Field_A ist dein Primärschlüssel, dann sollte man es nicht ändern. Sonst, alle Ihre Tabelle neu geordnet werden jedes mal, wenn Sie aktualisiert ein paar Aufzeichnungen, die wäre eine Menge Arbeit für Ihre HD /Prozessor. In diesem Fall sollten Sie eine andere PK, und erstellen Sie einen index für Field_A, nicht PK.
Zur Verbesserung der Leistung, die Sie verwenden können
UpdateBatch
Methode der ADODB-Objekt. Aber um diese Funktion zu nutzen, Bedarf es:adOpenStatic
cursorType undadLockBatchOptimistic
LockTypeauf das recordset-Objekt.
Zusätzlich können Sie auch
adUseClient
CursorLocation haben Last auf dem client anstatt der server während des Betriebs.Weiter geht, es unterlassen, mit
rec.EOF
test. Sollten Sie stattdessen die for-Schleife ab1 to rec.RecordCount
Verwenden Sie folgenden code als Hinweis:
Es ist jetzt schon mehr als 3 Jahre, wenn ich wechselte von
VB
zuPHP
. Möglicherweise fehlen einige tracks hier.Please note:
Ich habe nicht ausgeführt, diesen code noch. Es kann kleinere Probleme geben, doch sollte dies ausreichend sein, für die Anzeige Zweck.Sie können auch versuchen, um split-Chargen in Fragmente zu sehen, die Auswirkungen auf die performance.