Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Zugriff auf Access DB sehr langsam (https://www.delphipraxis.net/99552-zugriff-auf-access-db-sehr-langsam.html)

der_karlheinz 13. Sep 2007 21:00

Datenbank: Access • Version: 2000 • Zugriff über: ADO

Zugriff auf Access DB sehr langsam
 
Hallöchen,

ich habe ein kleines Problem mit meiner Access DB, die an die 50000 Datensätze gesammelt hat.

Wenn ich versuche einen neuen Datensatz anzulegen, hängt das ganze Programm gute 1,5 Minuten,
bis das sich wieder was bewegt.

Mit steigenden Datensätzen, wirds schlimmer, aber 50000 Datensätze sollten doch für eine Datenbank nicht viel sein?

Hier mal mein Code:

Delphi-Quellcode:
procedure TTabelle.Timer1Timer(Sender: TObject);
begin
   DataModule1.ADOtable1.Append;
   DataModule1.ADOtable1.FielValues['Date'] := now;
   DataModule1.ADOtable1.FielValues['Time'] := now;
   DataModule1.ADOtable1.FielValues['TS'] := now;
   DataModule1.ADOtable1.FielValues['Wert1'] := strtoint(SDIAppForm.E_Wert1.Text);
   DataModule1.ADOtable1.FielValues['Wert2'] := strtoint(SDIAppForm.E_Wert2.Text);
   DataModule1.ADOtable1.FielValues['Wert3'] := strtoint(SDIAppForm.E_Wert3.Text);
   DataModule1.ADOtable1.FielValues['Wert4'] := strtoint(SDIAppForm.E_Wert4.Text);
   DataModule1.ADOtable1.FielValues['Wert5'] := strtoint(SDIAppForm.E_Wert5.Text);
   DataModule1.ADOtable1.FielValues['Wert6'] := strtoint(SDIAppForm.E_Wert6.Text);
   DataModule1.ADOtable1.FielValues['Wert7'] := strtoint(SDIAppForm.E_Wert7.Text);
   DataModule1.ADOtable1.FielValues['Wert8'] := strtoint(SDIAppForm.E_Wert8.Text);
   DataModule1.ADOtable1.FielValues['Wert9'] := strtoint(SDIAppForm.E_Wert9.Text);
   DataModule1.ADOtable1.FielValues['Wert10'] := strtoint(SDIAppForm.E_Wert10.Text);
   DataModule1.ADOtable1.Post;
end;

Die Eigenschaften von ADOConnection:
Attributes.xaCommitRetaining = False
Attributes.xaAbortRetaining = False
CommandTimeout = 30
Connected = True

ConnectionString = Provider=Microsoft.Jet.OLEDB.4.0;User ID =Admin;Data Source=C:\Test\db.mdb;Mode=ReadWrite;Extended Properties="";Jet OLEDB:System database="";Jet OLEDB:Registry Path:"";Jet OLEDB:Database Password="";Jet OLEDB:Engine Type=4;Jet OLEDB:Database Locking Mode=0;Jet OLEDB:Global Partial Bulk Ops=2;Jet OLEDB:Global Bulk Transactions=1;Jet OLEDB:New Database Password="";Jet OLEDB:Create System Database=False;Jet OLEDB:Encrypt Database=False;Jet OLEDB:Don't Copy Locale on Compact=False;Jet OLEDB:Compact Without Replica Repair=False;Jet OLEDB:SFP=FALSE

ConnectionTimout = 15
ConnectOptions = coConnectUnspecified
CursorLocation = clUseClient
DefaultDatabase =
IsolationLevel = ilCursorStability
KeepConnection = True
LoginPromt = False
Mode = cmReadWrite
Name = ADOConnection1
Provider = Microsoft.Jet.OLEDB.4.0
Tag = 0
___________________________________
Die Eigenschaften von DataSource1:

AutoEdit = True
DataSet = ADOTable1
Enabled = True
Name = DataSource1
Tag = 0
___________________________________
Die Eigenschaften von DataSource2:

AutoEdit = False
DataSet = ADOTable2
Enabled = True
Name = DataSource2
Tag = 0
__________________________________
Die Eigenschaften von ADOTable1

Active = True
AutoCalcFields = True
CacheSize = 1
CommandTimeout = 30
Connection = ADOConnection1
ConnectionString =
CursorLocation = clUseClient
CursorType = ctStatic
EnableBCD = True
Filter =
Filtered = False
IndexFieldNames=
IndexName=
LockType = ItOptimistic
MarshalOptions = moMarshalAll
MasterFields=
MasterSource=
MaxRecords=0
Name=ADOTable1
ReadOnly = False
TableDirect = False
TableName=Tabelle1
Tag=0
_______________________________
Die Eigenschaften von ADOTable2 unterscheiden sich von ADOTable1 nur in:

Name=ADOTable2
TableName=Tabelle2


Ich hoffe Ihr könnt mir helfen!

Mit freundlichem Gruß
der_karl

mkinzler 13. Sep 2007 21:08

Re: Zugriff auf Access DB sehr langsam
 
Führst du den Code in einem Timer aus?
Hast du schon mal mit einem AdoQuery versucht?

Bernhard Geyer 13. Sep 2007 21:22

Re: Zugriff auf Access DB sehr langsam
 
Für Access: CursorLocation = cUserServer
Ansonsten hast du deine 50.000 Datensätze immer doppelt im Speicher.
Ansonsten solltest du mit INSERT-Statements arbeiten und TADODatasets statt TADOTable sowie nur benötigte Datensätze per Where-Bedingung abfragen.

der_karlheinz 14. Sep 2007 08:48

Re: Zugriff auf Access DB sehr langsam
 
Hallo,

@mkinzler:
Ja, alle 3 Minuten wird die Prozedur durch ein OnTimer Ereignis aufgerufen,
da die Werte alle 3 Minuten automatisch in die Datenbank eingefügt werden sollen.
Ist das TADOQuery nicht eigentlich zur Abfrage einer Datenbank?

@Bernhard Geyer
Habe bei TADOConnection und beim TADOTable die Eigenschaft für die CursorLocation geändert, aber leider
wirds auch nicht schneller :(

Ich werds gleich mal mit TADODatasets versuchen, nur leider bekomm ich in der Hilfe nichts angezeigt (Text kann nicht angezeigt werden).


Mit freundlichem Gruß

der_karl

mkinzler 14. Sep 2007 09:11

Re: Zugriff auf Access DB sehr langsam
 
Zitat:

Ist das TADOQuery nicht eigentlich zur Abfrage einer Datenbank?
Nein, man kann damit SQL-Statements absetzen.
Neben SELECT ist auch INSERT + UPDATE möglich. Bei DML-Statements (INSERT, DELETE, UPDATE) ohne das Daten vom zurück an den Client geschrieben werden müssen.
Ich würde hierfür eine parametrisierte Abfrage nehmen

SQL-Code:
Insert into <Tabelle>(<feldliste>) values ( :feld1, :feld, ...);
So müssen beim insert nur die Parameter (Feldwerte) Setzen.

der_karlheinz 14. Sep 2007 09:14

Re: Zugriff auf Access DB sehr langsam
 
Hmm, das ganze scheint schon zu hängen, wenn ich die ADOConnection auf True setze,
dann hängt das ganze schon das erste mal,
hab mit TADODataSet mal folgendes probiert:

Delphi-Quellcode:
procedure TTabelle.Timer1Timer(Sender: TObject);
begin
   DataModule1.ADODataSet1.CommandText := 'INSERT INTO Ofen20 (Date) VALUES (' + DateToStr(now) + ')';
   DataModule1.ADODataSet1.Active := true;
   DataModule1.ADODataSet1.Post;
   DataModule1.ADODataSet1.Active := false;
end;
scheint aber noch der Wurm drin zu sein.
(Da ich TADODataSet1 ohne CommandText nicht auf Activ = True setzen kann, hab ichs so versucht,
sind ja mehr als 10 Werte/Datensatz)

hoika 14. Sep 2007 09:20

Re: Zugriff auf Access DB sehr langsam
 
Hallo,

nimm eine ADOQuery.


Heiko

der_karlheinz 14. Sep 2007 09:22

Re: Zugriff auf Access DB sehr langsam
 
So, versuche jetzt mein Glück mit der ADOQuery,...

@mkinzler:

Hab ich das richtig Versanden:

SQL-Code:
Insert into <Tabelle1>(<Date>,<Time>,<Wert1>) values ( :now, :now, :now, :(+StrToInt(Textfeld_Wert1)+),...);
(Sorry, wegen der vielleicht blöden Frage, kämpfe nur gerade damit irgendwie die Hilfedatei angezeigt zu bekommen)

Meine Daten werden jetzt schonmal in der Tabelle angezeigt,
habe das ADOTable gegen ADOQuery getauscht, und bei der Eigenschaft SQL

SQL-Code:
select * from Tabelle1
eigegeben.

Soweit so gut, wie kann ich jetzt das SQL Statement (Insert...) abschicken?

Gruß
der_karl

*Schonmal einen großen Dank hier lass*

mkinzler 14. Sep 2007 09:30

Re: Zugriff auf Access DB sehr langsam
 
die <> bezeichneten Platzhalter. Statt der Typen musst du die Feldnamen angeben und satt den werten die Parameternamen:

SQL-Code:
Insert into Tabelle1( datum, von, bis, ...) values ( :datum, :von, :bis,...)
Im Timer brauchst du das staement dann nicht mehr zu setzen, sondern nur die Feldwerte

Delphi-Quellcode:
AdoQuery1.Parameters.ParamByName( 'datum').value := ...;
...

und dann mit
Delphi-Quellcode:
 AdoQuery1.ExecSQL;
die Abfrage ausführen.

Wobei du auch standardwerte ( Now) direkt bei der Definition der fFlder angeben kannst.

der_karlheinz 14. Sep 2007 09:38

Re: Zugriff auf Access DB sehr langsam
 
Ahh :-D habs verstanden.

Werd ich heut Nachmittag gleich ausprobieren.

grenzgaenger 15. Sep 2007 13:36

Re: Zugriff auf Access DB sehr langsam
 
an deiner stelle würd ich auch mal die datenbank komprimieren... vielleicht hift dies...

der_karlheinz 15. Sep 2007 16:05

Re: Zugriff auf Access DB sehr langsam
 
Komprimiert hatte ich die DB schon, hat nur ein paar Sekunden gebracht, leider
das nicht den gewünschten erfolg gebracht.
Das Abrufen der Daten aus der DB funktioniert ja wunderbar,
nur schreiben dauert ewig.

Werde mich heut abend mal dran setzen, das Schreiben mit
dem ADOQuery fertig zu Programmieren.

der_karlheinz 17. Sep 2007 12:02

Re: Zugriff auf Access DB sehr langsam
 
Soo, der Schreibzugriff auf die Datenbank ist jetzt schon erheblich fixer,...

hab in der FAQ was gefunden, und ausprobiert

Delphi-Quellcode:
DataModule1.ADOQuery.SQL.Text := 'SELECT * FROM tabelle WHERE 0=1';
DataModule1.ADOQuery.Open;

DataModule1.ADOQuery.Append;
DataModule1.ADOQuery['Date'] := now;
DataModule1.ADOQuery['Time'] := now;
...
...
DataModule1.ADOQuery.Post;

DataModule1.ADOQuery.Close;
Jetzt hängts nur noch beim Programmstart (für ne Zeitlang > 50% Auslastung).
Ich habe ja noch eine DBGird und eine TeeChart Komponente, die auf die DB zugreifen, um das ganze zu Visualisieren.

Dafür habe ich noch ein TADOTable, das ich zusammen mit TADOConnect auf Activ bzw. Connected = TRUE gestellt habe.

Ich denke das das beim Programmstart dafür sorgt, das die CPU erstmal in die Knie geht.

Gibt es da vielleicht einen ähnlichen Lösungsweg für?

Die Tabelle und das Diagramm sollten alle Paar Minuten einen Refresh durchführen, das klappt auch wunderbar,
ohne das das Programm hängt. Nur beim Starten des Programms, dauerts.

hoika 18. Sep 2007 13:09

Re: Zugriff auf Access DB sehr langsam
 
Hallo,

<< Ich denke das das beim Programmstart dafür sorgt, das die CPU erstmal in die Knie geht. >>

Warum probierst du das nicht einfach aus ?.
BreakPoint auf deine 1. Anweisung und los geht's.

In meinen Programmen wird beim Start nur ein Connect gemacht.
Alles andere, wenn der Nutzer was will.

Isdt das DBGrid offen beim Start ?
Was steht drin ?
Alle Einträge? Wenn ja, warum ?


Heiko

der_karlheinz 18. Sep 2007 18:42

Re: Zugriff auf Access DB sehr langsam
 
Hallo Heiko,

hab mich mal mit dem Debugger durch den Programmaufruf bewegt.

In der Projekt Unit hängts bei Application.CreateForm(DatenModul) (hoffe ich habs jetz richtig geschrieben,
habs Programm auf einem andern Rechner).

Hmm, ich habe eine seperate Form, in der ich das DBGird habe, und eine seperate Form,
wo ich das TeeChart drin habe,
das DBGird zeigt mir alle Datensätze an.
Es müssten nicht alle Einträge angezeigt werden, mir würden von den 50000 Datensätzen
z.B. die letzten 100 reichen, wenn ich die Möglichkeit habe mich dann noch über
Schaltflächen oder einen Filter weiter zu bewegen (in alten Datensätzen).

Im TeeChart bewege ich mich ja mit der Next und Previous Methode in den Datensätzen
(da wird wohl nicht die ganze DB erst gelesen???)

Ich denke ich habe das Problem verstanden,
mir fehlt nur der Lösungsansatz.

Gibt es eigentlich spezielle Bücher oder ebooks, die sich mit SQL im Bezug auf Borlands Delphi beschäftigen?

hoika 18. Sep 2007 18:51

Re: Zugriff auf Access DB sehr langsam
 
Hallo,

dann setz mal nen Breakpoint in das Create des DataModuls.
Ist die Query (für das DBGrid) zur Designzeit schon offen?
Mache es mal zu und erst im Create des DataModusl auf.

Dein Problem wird wohl das "50000 Datensätze sein".

Das DBGrid lädt alle Datensätze, um sie in dem Grid anzuzeigen,
im DB-Entwicklung mit Delphi (Andreas Kosch)
stand aber zumindestens mal was mit Verwendung von Bookmarks.

Warum müssen 500000 angezeigt werden ?
Das macht überhaupt keinen Sinn.
Baue eine Suchfunktion ein,
die immer nur eine kleine Teilmenge anzeigt.


Heiko

der_karlheinz 19. Sep 2007 07:22

Re: Zugriff auf Access DB sehr langsam
 
So, ich versuche jetzt die Datensätze im DBGird zu Filtern,

wenn ich folgendes Versuche (Die Variablen filter_von und filter_bis sind als TDateTime Global definiert)

Delphi-Quellcode:
procedure TTabelle.B_Filter_updateClick(Sender: TObject);
var
Datumsformat: TFormatSettings;
von: String;
bis: String;
begin
  Datumsformat.DateSeparator:='-';
  Datumsformat.ShortDateFormat:='yyyy-dd-mm';
  Datumsformat.TimeSeparator:=':';
  Datumsformat.ShortTimeFormat:='HH:mm:ss';

  von:= (E_von_jahr.Text + ('-') + E_von_monat.Text + ('-') + E_von_tag.Text);
  bis:= (E_bis_jahr.Text + ('-') + E_bis_monat.Text + ('-') + E_bis_tag.Text);
  filter_von:=(StrToDateDef(von, -10, Datumsformat) + StrToTimeDef('00:00:00', -10, Datumsformat));
  filter_bis:=(StrToDateDef(bis, -10, Datumsformat) + StrToTimeDef('23:59:00', -10, Datumsformat));

  Edit1.Text:=datetostr(filter_von);
  Edit2.Text:=datetostr(filter_bis);

  DataModule1.ADOQuery_DBGird.Close;
  DataModule1.ADOQuery_DBGird.SQL.Text := 'SELECT * FROM tabelle WHERE Date BETWEEN filter_von AND filter_bis';
  DataModule1.ADOQuery_DBGird.Open;


end;
bekomme ich beim Ausführen die Fehlermeldung "filter_von" hat keinen Standartwert.

Woran kann das liegen??? :gruebel:

hoika 19. Sep 2007 07:53

Re: Zugriff auf Access DB sehr langsam
 
Hallo,

DataModule1.ADOQuery_DBGird.SQL.Text := 'SELECT * FROM tabelle WHERE Date BETWEEN filter_von AND filter_bis';

Du schreibst das direkt als String.

Delphi-Quellcode:
DataModule1.ADOQuery_DBGird.SQL.Text :=
  'SELECT * FROM tabelle WHERE Date BETWEEN :filter_von AND :filter_bis';
DataModule1.ADOQuery_DBGird.ParamByName('filter_von').AsDateTime:= tdtFilter_von;
DataModule1.ADOQuery_DBGird.ParamByName('filter_bis').AsDateTime:= tdtFilter_bis;
Ich habe auch gleich mal nen tdt davorgesetzt,
dann ist es leichter zu verstehen, was eine Variable für einen Typ hat.


Heiko

der_karlheinz 19. Sep 2007 08:42

Re: Zugriff auf Access DB sehr langsam
 
Das Problem ist gelöst,...

Delphi-Quellcode:
  DataModule1.ADOQuery_Ofen_DBGird.Close;
  DataModule1.ADOQuery_Ofen_DBGird.SQL.Text := 'SELECT * FROM Ofen20 WHERE Date BETWEEN :filter_von AND :filter_bis';
  DataModule1.ADOQuery_Ofen_DBGird.Parameters.ParamByName('filter_von').Value:= tdtFilter_von ;
  DataModule1.ADOQuery_Ofen_DBGird.Parameters.ParamByName('filter_bis').Value:= tdtFilter_bis;
  DataModule1.ADOQuery_Ofen_DBGird.Open;
mal sehen, ob das Programm jetzt schneller startet.

Wie sieht das mit dem DBChart aus?
Wird da auch erst die ganze Tabelle eingelesen?


Gruß
Stephan

hoika 19. Sep 2007 09:39

Re: Zugriff auf Access DB sehr langsam
 
Hallo,

kommt auf das DataSource -> DataSet an des DBChart an.


Heiko


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:10 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz