none
Ursache für Aufblähen der Datenbank gesucht RRS feed

  • Frage

  • Hallo

    Für eine statistische Auswertung muss ich Daten, die in Form von Textdateien (UTF8) bis 200 MB Größe eingehen, in eine Tabelle in Access einlesen und verarbeiten. Im letzten Jahr gab es dabei keinerlei Probleme, zB:
    Datenbankgröße vor dem Einlesen: 5MB
    Textdatei einzulesen: 170MB
    Datenbankgröße nach dem Einlesen der Textdatei: 500MB
    Tabelle mit Inhalt aus Textdatei in der Datenbank: 1,7 Mio Datensätze mit etwa 120 Zeichen und 250 Byte je Datensatz im Editor
    Datenbankgröße nach dem Verarbeiten: 900MB
    Datenbankgröße nach dem Komprimieren: 500MB

    In diesem Jahr bleibe ich hängen, weil die Datenbank das Limit erreicht.
    Das passiert in folgender Prozedur an der Marke HIER:
    Dim d As New ADODB.Recordset, s As New ADODB.Recordset 
    d.Open "select * from Daten order by pzn desc, [vo-datum] desc;", CurrentProject.Connection, adOpenForwardOnly, adLockPessimistic ' 
    s.Open "select * from Stamm_PZN order by pzn desc, [stand] desc;", CurrentProject.Connection, adOpenForwardOnly, adLockReadOnly ' 
    d.MoveFirst 
    s.MoveFirst 
    
    Do 
    Select Case True 
    Case d!pzn < s!pzn 
    s.MoveNext 
    If s.EOF = True Then Exit Do 
    Case d!pzn > s!pzn 
    d.MoveNext 
    If d.EOF = True Then Exit Do 
    Case Else 
    'If d![vo-datum] >= cJJJJ & s!stand Then 'ABDATA 
    If d![vo-datum] >= s!stand Then 'WIDO 
    d!ATC = s!ATC  'Text, 7 Zei
    d!DDD = s!DDD  'Zahl Single
    d!Biosim = s!Biosim  'Zahl, Integer
    d!BTM = s!BTM  'Zahl, Integer
    HIER: d.MoveNext 'je Datensatz mit 250 Byte entstehen zusätzlich 4 kB 
    If d.EOF = True Then Exit Do 
    Else 
    s.MoveNext 
    If s.EOF = True Then Exit Do 
    End If 
    End Select 
    Loop 
    Recordset d enthält Bewegungsdaten. Diese sollen zu einem Datum (vo-datum) mit zu dem Zeitpunkt gültigen Stammdaten (gültig ab stand) aus s ergänzt werden.

    Wenn ich durch die Prozedur debugge, verändert sich die DB-Größe wie folgt:
    Start der Prozedur 456 MB
    Recordset d öffnen danach 456 MB (1,8 Mio. DS)
    Recordset s öffnen danach 456 MB (150T DS)
    Do … Loop 2,1 GB werden vor Beendigung der Schleife erreicht


    Datenbank, Code, Tabellen und Datenaufkommen sind im Grunde genommen gleich. Einzige Variable scheint mir mein neuer Rechner zu sein, Win 10, 64 Bit.
    Vorher Win 7, 64 Bit mit Office Professional 2010.
    Auf dem neuen Rechner wurde dasselbe Office-Paket wie auf dem alten PC installiert.

    Leider kann ich den alten Rechner nicht mehr auftreiben, der wurde entsorgt.

    Ein Auslagern von Tabellen bringt nichts. Bei 1,8 Mio. Datensätzen und zusätzlich 4 kB je Update für einen Datensatz mit 250 Byte im Editor entstehen schlappe 7 GB. 

    Ich habe auch schon mit DAO probiert, ähnlich.

    Ein Update über SQL und Joins geht auch nicht so ohne weiteres, dazu müsste erstmal eine Zwischentabelle  mit 70.000 mal 12 Datensätzen erstellt und mit eingebunden werden, weil dann zu jeder PZN für jeden Monat die Stammdaten zur Verfügung gestellt werden müssten.

    Ich habe den Code in der Hoffnung, dass die Datenbankgröße dadurch nicht beeinflusst wird, in Excel mit Provider=MSDASQL;Driver={Microsoft Access Driver (*.mdb, *.accdb)} sowohl mit Primary Key als auch ohne  ausführen lassen. Da kommt an der Marke HIER der Fehler:
    Fehler -2147467259 (80004005)
    Microsoft ODBC-Treiber für Access: COUNT-Feld ungültig
    Die Ausführungen im Web zu diesem Fehler helfen mir auch nicht weiter.

    Ich bin ratlos, was kann dieses Aufblähen verursachen? 



    Mittwoch, 13. November 2019 12:56

Antworten

  • Hallo!

    Die Vergößerung könnte mit dem Anfügen einer Page zusammenhängen, sobald ein Textfeld vergrößert wird. Wenn der "Platz" im Recordset nicht ausreicht, wir eine zusätzliche Page benötigt. => Datenbank wächst um Seitengröße (bin nicht sicher, aber ich glaub es sind 4 KB) pro Datensatzänderung.

    Ist zwar schon älter, aber dürfte das gleiche Problem sein:
    https://www.ms-office-forum.net/forum/showthread.php?t=218359
    Interessant dabei: Das Problem trat nur beim Recordsetänderungen aber nicht bei Updateanweisungen auf.

    Komprimieren der DB sollte die Größe wieder reduzieren.

    Gruß
    Josef


    Code-Bibliothek für Access-Entwickler
    AccUnit - Testen von Access-Anwendungen
    Virtueller Access-Stammtisch

    Samstag, 16. November 2019 11:08

Alle Antworten

  • Hallo Tom,

    ich kann dir bei der Datenmenge eigentlich nur den ernst gemeinten Rat geben: Nimm ein richtiges DBMS. Sei es Microsoft SQL, Postgre, MySQL, ... Alles, nur nicht Access und ähnliche Sachen.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET (2001-2018)
    https://www.asp-solutions.de/ - IT Beratung, Softwareentwicklung, Remotesupport

    Mittwoch, 13. November 2019 14:13
    Moderator
  • Hallo Stefan

    na gut, dass ich gerade einen neuen SQL-Server bekommen habe ;)

    Es wurmt mich aber dennoch, schließlich lief die Prüfung schon 2 Jahre durch. Schwierigkeiten gab es nur, wenn die Textdateien von einem Linux-Gerät kamen. Dann musste ich konvertieren.

    Mir ist da noch was aufgefallen. Ich bleibe nicht nur in dem oben beschriebenen Code hängen, sondern die Datenbank blähte bereits bis ans Limit auf beim Einlesen der Textdatei, die verknüpft ist über acLink, in eine Tabelle an der Stelle:

                rs2.AddNew
                 'update führt wohl zum Aufblähen
    '            rs2.Update "VOID", rs.Fields(6)
    '            rs2.Update "Nr", CStr(i)
    '            rs2.Update "Quartal", rs.Fields(3)
    
    

    Damit habe ich bezweckt, wenigstens Rümpfe von Datensätzen in der Datenbank zu haben, falls durch Datenmüll Datensätze nicht richtig angelegt werden, um Aussagen über die Datenqualität treffen zu können.
    Die restlichen Felder werden über AddNew gespeichert.

    D. h. also, die Datenbank bläht extrem auf, wenn einzelne Felder gespeichert werden. 

    Daraus folgernd habe ich obigen Code derart umgestellt, dass ich den kompletten Datensatz in eine separate Tabelle ablege. Und siehe da, der Code lief durch, die Datenbank ist jetzt mit 2 Tabellen Daten auf ca. das doppelte, 900 MB, angewachsen:

    d.Open "select * from Daten order by pzn desc, [vo-datum] desc;", CurrentProject.Connection, adOpenForwardOnly, adLockPessimistic  '
    d2.Open "Daten2", CurrentProject.Connection, adOpenForwardOnly, adLockPessimistic  '
    s.Open "select * from Stamm_PZN order by pzn desc, [stand] desc;", CurrentProject.Connection, adOpenForwardOnly, adLockReadOnly  '
    d.MoveFirst
    s.MoveFirst
    Do
        Select Case True
        Case d!PZN < s!PZN
            s.MoveNext
            If s.EOF = True Then Exit Do
        Case d!PZN > s!PZN
            d.MoveNext
            If d.EOF = True Then Exit Do
        Case Else
            If d![VO-Datum] >= s!stand Then  'WIDO
                
                d2.AddNew
                d2!BSNR9 = d!BSNR9
                d2!LANR9 = d!LANR9
                d2!Quartal = d!Quartal
                d2!VOID = d!VOID
                d2!Nr = d!Nr
                d2!PZN = d!PZN
                d2![VO-Datum] = d![VO-Datum]
                d2!EGKVNR = d!EGKVNR
                d2!GebDat = d!GebDat
                d2!VOF = d!VOF
                d2!Netto = d!Netto
                d2!ATC = s!ATC
                d2!DDD = s!DDD
                d2!BTM = s!BTM
                d2!Biosim = s!Biosim
                d2!xxNR9 = d!xxNR9
                d2!WP_FG = d!WP_FG
                d2!PArt = d!PArt
                d2!Wert = d!Wert
                d2!valid = d!valid
                
                d.MoveNext
                If d.EOF = True Then Exit Do
            Else
                s.MoveNext
                If s.EOF = True Then Exit Do
            End If
        End Select
    Loop
    d.Close
    d2.Update
    d2.Close
    s.Close
    
    Einen kompletten Datensatz zusätzlich anzulegen ist also Speichertechnisch effizienter als ein paar Felder zu aktualisieren. Ist das nachvollziehbar?
     Gruß Tom

    Donnerstag, 14. November 2019 13:22
  • Hallo!

    Die Vergößerung könnte mit dem Anfügen einer Page zusammenhängen, sobald ein Textfeld vergrößert wird. Wenn der "Platz" im Recordset nicht ausreicht, wir eine zusätzliche Page benötigt. => Datenbank wächst um Seitengröße (bin nicht sicher, aber ich glaub es sind 4 KB) pro Datensatzänderung.

    Ist zwar schon älter, aber dürfte das gleiche Problem sein:
    https://www.ms-office-forum.net/forum/showthread.php?t=218359
    Interessant dabei: Das Problem trat nur beim Recordsetänderungen aber nicht bei Updateanweisungen auf.

    Komprimieren der DB sollte die Größe wieder reduzieren.

    Gruß
    Josef


    Code-Bibliothek für Access-Entwickler
    AccUnit - Testen von Access-Anwendungen
    Virtueller Access-Stammtisch

    Samstag, 16. November 2019 11:08
  • Hallo Josef

    ja, auch bei mir etwa 4 kB Zuwachs je Datensatzänderung.

    Es betrifft bei mir auch nur Spalten mit Strings.

    Wobei mir noch nicht klar ist, wie ich denn einen String nun, ohne dieses Problem zu verursachen, ändern kann. Sowohl in der Quell- als auch in der Zieltabelle  in meinem Beispiel ist die Spalte ATC jeweils mit 7 Zeichen festgelegt (Zieltabelle enthält anfangs "kA" und wird dann auf 7 Zeichen aufgestockt).

    Besten Dank für Deine erhellenden Hinweise, ich war schon drauf und dran, paranoid zu werden ;)

    Gruß Tom

    Montag, 18. November 2019 11:34