AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Access zu langsam

Offene Frage von "kolio"
Ein Thema von kolio · begonnen am 5. Jul 2005 · letzter Beitrag vom 6. Jul 2005
Antwort Antwort
kolio

Registriert seit: 30. Jan 2005
Ort: Plauen
9 Beiträge
 
#1

Access zu langsam

  Alt 5. Jul 2005, 21:56
Datenbank: Access • Version: 2000 • Zugriff über: ADOQuery
Hallo,

wer kann mir helfen? Ich muss jeweils 20 bis 30 Seriennummern aus einer TListBox in eine Access Datenbank übernehmen, welche sich auf dem Server befindet. Für jede Seriennummer soll ein eigener Datensatz angelegt werden. Je nach verwendeten PC geht es manchmal mit SQL-Befehlen und manchmal mit "ADODataSet.Edit / Append / Post" schneller. Prinzipiell würde ich aber SQL bevorzugen.

Das nachfolgende Beispiel benötigt auf einem 1 GHz Rechner ca. 10 s für 30 Datensätze.

Delphi-Quellcode:
function TForm1.WriteSNr: Boolean;
var
  i: Integer;
begin
  try
    for i := 0 to ListBox1.Count - 1 do
    begin
      ADOQuery4.Close;
      ADOQuery4.SQL.Text := 'INSERT INTO Tabelle4 (Seriennummer) ' +
                            'VALUES (:PSeriennummer)';
      ADOQuery4.Parameters.ParamByName('PSeriennummer').Value := ListBox1.Items.Strings[i];
      ADOQuery4.ExecSQL;
      Result := True;
    end;
  except
    Result := False;
  end;
end;
Wie kriege ich das schneller hin?

Vielen Dank schon mal ...
  Mit Zitat antworten Zitat
jensw_2000
(Gast)

n/a Beiträge
 
#2

Re: Access zu langsam

  Alt 6. Jul 2005, 00:19
Mit diesem "kleinen" Insert solltest du über eine 100MBit Verbindung mehrere Hundert Datensätze pro Sekunde in die DB Schieben.

Das Problem liegt sicher woanders.

Hast du schon mal probiert die DB testweise auf deinen lokalen PC zu legen, um Netzwerk- oder Serverprobleme auszuschließen?

Hängen eventuell irgendwelche datensensitiven Komponenten an einer Datasource die mit deiner ADOQuery4 verbunden ist ? Wenn ja, dann hänge die Datasource ab oder verbaue DisableControls und EnableControls.
z.B. so ...

Delphi-Quellcode:
function TForm1.WriteSNr: Boolean;
var
  i: Integer;
begin
  try
    try
     Result := False; // init
     ADOQuery4.DisableControls; // <<<<
     for i := 0 to ListBox1.Count - 1 do
       begin
         ADOQuery4.Close;
         ADOQuery4.SQL.Text := 'INSERT INTO Tabelle4 (Seriennummer) ' +
                               'VALUES (:PSeriennummer)';
         ADOQuery4.Parameters.ParamByName('PSeriennummer').Value := ListBox1.Items.Strings[i];
         ADOQuery4.ExecSQL;
         Result := True;
       end;
    finally
      ADOQuery4.EnableControls; // <<<<
    end;
  except
    Result := False;
  end;
end;
Wenn beides nicht hilft versuche mal deine Access DB zu reparieren und zu komprimieren bzw. aktuelle JET Treiber zu installieren.

Sorry,
was Genaueres kann ich dir erstmal nicht anbieten.
0,3 Sek pro Datensatz ist extrem zuviel und deine INSERT Function sieht OK aus.

Schöne Grüße,
Jens

  Mit Zitat antworten Zitat
Robert_G
(Gast)

n/a Beiträge
 
#3

Re: Access zu langsam

  Alt 6. Jul 2005, 00:45
Moin Jens,
Du darfst nicht vergessen, dass Jet nur eine Desktop DB engine ist.
Er wird also _immer_ fast alle DS hin und her schieben, genauso wie er auch ständig nachschaut, ob sie geändert wurde.
Und beim "Öffnen" wird das Ding tatsächlich "geöffnet" als ob es ein Dokument in Word wäre. (was natürlich darin resultiert, dass es komplett geladen wird.... )

Den Sinn von sowas kapiere ich auch nicht ganz... Entweder lokale DB, oder nicht.
Solche Spielereien wie eine Jet DB auf einen Fileserver zu packen sind mir irgendwie schleierhaft...
  Mit Zitat antworten Zitat
supermuckl

Registriert seit: 1. Feb 2003
1.340 Beiträge
 
FreePascal / Lazarus
 
#4

Re: Access zu langsam

  Alt 6. Jul 2005, 00:47
da access keine serverbasierte DB ist, wird immer die gesamte DB als file hin und her kopiert - wenn das über netzwerk oder gar internet passiert, geht das natürlich umso langsamer je größer die db und je langsamer die verbindung zur freigabe der DB
Das echte Leben ist was für Leute...
... die im Internet keine Freunde finden!
  Mit Zitat antworten Zitat
Benutzerbild von x000x
x000x

Registriert seit: 21. Jan 2004
Ort: Bei Hamburg
308 Beiträge
 
Delphi XE2 Professional
 
#5

Re: Access zu langsam

  Alt 6. Jul 2005, 00:58
Moin moin,

also ob es durch meinen Hinweis merklich (bei 30 DS) schneller wird, ist fraglich... aber trotzdem:
Delphi-Quellcode:
function TForm1.WriteSNr: Boolean;
var
  i: Integer;
begin
  try
     ADOQuery4.Close;
     ADOQuery4.SQL.Text := 'INSERT INTO Tabelle4 (Seriennummer) ' +
                           'VALUES (:PSeriennummer)';
     ADOQuery4.Prepared := True;
     for i := 0 to ListBox1.Count - 1 do begin
         ADOQuery4.Parameters.ParamByName('PSeriennummer').Value := ListBox1.Items.Strings[i];
         ADOQuery4.ExecSQL;
     end;
     Result := True;
  except
    Result := False;
  end;
end;
1. Die Datenmenge muss bei ExecSQL nicht immer wieder geschlossen werden, da keine geöffnet wird...
2. Das SQL Statement muss nicht bei jedem Durchlauf der Schleife neu gesetzt werden...
3. Prepared auf True setzen (Ob das bei Access auch was nützt??? ... hab keine Ahnung)
4. Result kann nach der Schleife gesetzt werden, da ja im Fehlerfall eh False

PS: Punkt 4 bringt dir bestimmt die erhoffte Geschwindigkeit
Peter
-= Gruss Peter =-
-= alias x000x =-
  Mit Zitat antworten Zitat
jensw_2000
(Gast)

n/a Beiträge
 
#6

Re: Access zu langsam

  Alt 6. Jul 2005, 05:53
Zitat:
Moin Jens,
Du darfst nicht vergessen, dass Jet nur eine Desktop DB engine ist.
Er wird also _immer_ fast alle DS hin und her schieben, genauso wie er auch ständig nachschaut, ob sie geändert wurde.
Und beim "Öffnen" wird das Ding tatsächlich "geöffnet" als ob es ein Dokument in Word wäre. (was natürlich darin resultiert, dass es komplett geladen wird.... )
war wohl doch etwas spät gestern ...


OK, dann teste es doch mal so ...

Delphi-Quellcode:
  Result:=true;
  try
    ADOQuery4.Close;
    ADOQuery4.SQL.Clear;

    for i := 0 to ListBox1.Count - 1 do
    begin
      ADOQuery4.SQL.Add := 'INSERT INTO Tabelle4 (Seriennummer) ' +
                            'VALUES ('+ListBox1.Items.Strings[i]+')';
    end;
    ADOQuery4.ExecSQL;
  Except
     On E:Exception do
     begin
       Result :=false;
       showmessage('Beim Speichern ist folgender Fehler aufgetreten: '+#13#10+e.Message);
     end;
  end;
Damit öffnest du die DB nur einmal.
  Mit Zitat antworten Zitat
Delphi_Fanatic

Registriert seit: 24. Mär 2004
201 Beiträge
 
#7

Re: Access zu langsam

  Alt 6. Jul 2005, 07:09
Zitat:
Prepared auf True setzen (Ob das bei Access auch was nützt??? ... hab keine Ahnung)
Bringt auch bei Access was, aber man sollte auch das unprepare nicht vergessen.

Im Übrigen lässt sich bei Access eine erhebliche Geschwindigkeitssteigerung erzielen, wenn man die Cursor-Location von Clientsided auf Serversided umstellt.

Generell kann man schon sagen, dass man mit Access auch bei gemeinsamen Zugriffen im Netz gut arbeiten kann, solange die Anzahl von Datensätzen pro Tabelle nicht mehr als einige (wenige) Zehntausend sind.

Und irgendwelche umfangreichen Batch-Jobs, die z.B. 10.000 Datensätze neu einfügen oder löschen oder sonst was - die lässt man üblicherweise sowieso nicht tagsüber laufen, sondern eben nachts im Rahmen von automatisch ausgeführten Jobs.
  Mit Zitat antworten Zitat
kolio

Registriert seit: 30. Jan 2005
Ort: Plauen
9 Beiträge
 
#8

Re: Access zu langsam

  Alt 6. Jul 2005, 21:21
Hallo zusammen,

erst mal vielen Dank für die zahlreichen Hinweise, die werde ich jetzt mal austesten. Übrigens, um exakte Zeiten zu ermitteln nutze ich die Kompo "HPCounter", funktioniert super, Auflösung ist 1 Mikrosekunde.

Ich möchte mal meine Anwendung präzisieren:
Über einen Handscanner werden Seriennummern verschiedener Produkte in eine ListBox geschrieben und dann in die DB übernommen. Die DB besteht aus 3 verknüpften Tabellen. In der 1. sind die verschiedenen Produkte, in der 2. die Seriennummern der jeweiligen Produkte und in der 3. die Infos zur jeweiligen Seriennummer. Um die ganze Sache zu beschleunigen schreibe ich die ListBox erst mal in eine Hilfstabelle die immer leer ist. Mit je einem SQL-Befehl werden alle Seriennummern in die Tabelle 2 und alle Infos dazu in Tabelle 3 übernommen. Das bringt schon mal ca. 60 bis 70 % Zeitersparnis gegenüber dem direkten Schreiben in Tabelle 2 und 3. Der Flaschenhals ist, die 20 ... 30 Seriennummern von der ListBox in die Hilfstabelle zu bringen. Was ich mir noch überlegt habe ist, für die Hilfstabelle eine separate lokale Datei zu verwenden.
  Mit Zitat antworten Zitat
kolio

Registriert seit: 30. Jan 2005
Ort: Plauen
9 Beiträge
 
#9

Re: Access zu langsam

  Alt 6. Jul 2005, 22:20
Ich noch mal ...

Hab alles getestet, allerdings nur lokal auf meinem 1,4 GHz P4 mobile. Geschwindigkeitszuwachs gleich Null. Für 30 Datensätze brauche ich genau 1,6 Sekunden.
Werde es morgen mal mit der DB auf dem Server probieren.


Was allerdings nicht funktioniert ist dieser Vorschalg :
Delphi-Quellcode:
Result:=true;
  try
    ADOQuery4.Close;
    ADOQuery4.SQL.Clear;

    for i := 0 to ListBox1.Count - 1 do
    begin
      ADOQuery4.SQL.Add := 'INSERT INTO Tabelle4 (Seriennummer) ' +
                            'VALUES ('+ListBox1.Items.Strings[i]+')';
    end;
    ADOQuery4.ExecSQL;
  Except
     On E:Exception do
     begin
       Result :=false;
       showmessage('Beim Speichern ist folgender Fehler aufgetreten: '+#13#10+e.Message);
     end;
  end;
War bei dieser Sache sowieso skeptisch, da werden doch einfach nur alle SQL-Kommandos hintereinander geschrieben.

Tschau
  Mit Zitat antworten Zitat
jensw_2000
(Gast)

n/a Beiträge
 
#10

Re: Access zu langsam

  Alt 6. Jul 2005, 23:31
Zitat:
War bei dieser Sache sowieso skeptisch, da werden doch einfach nur alle SQL-Kommandos hintereinander geschrieben.
Genau.
Das nennt sich BULK INSERT Script.

Bei erwachsenen SQL Servern wird jeder Befehl mit einem GO (als "Befehlsende") abgeschicht.
Access verwendet anstatt des "go" ein Semikolon zum abschicken des Befehls.

Hätte also durchaus klappen können

Da ich den "nicht funktionierenden" Code nicht auf mit sitzen lassen wollte, habe ich jetzt eine Weile gegoogelt und lernen dürfen, das ACCESS keine BULK INSERTS unterstützt.

Tut mir Leid falls du dir dadurch unnötig Arbeit gemacht hast, aber der Weg wäre imho bei jeder anderen DB richtig gewesen.


Schöne Grüße,
Jens

  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:55 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz