Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi SQL-Abfrage zu langsam (https://www.delphipraxis.net/186511-sql-abfrage-zu-langsam.html)

geosucher 8. Sep 2015 11:34

Datenbank: MS Access • Version: 2003 • Zugriff über: ADO

SQL-Abfrage zu langsam
 
Hallo zusammen,

schreibe mit Delphi 2010 an einem Programm mit ADO-Zugriff auf eine Access 2003-Datenbank.
Ich habe eine Abfrage in meinem Programm in der Art

"select dx,dy where (rw >= x-1000) and (rw <= x +1000) and (hw >= y-1000) and (hw>= y+1000)

rw,hw,dx und dy sind DB-Felder, xund y sind variabel. Wenn ich die Abfrage per ADODataset realisiere, funktioniert alles, ist aber sehr langsam.
Meine Idee: Die Abfrage im Access generieren, aber wie?

Danke für Eure Tipps!

Gruß

Geosucher

nahpets 8. Sep 2015 11:56

AW: SQL-Abfrage zu langsam
 
Mit between?
Code:
select dx,dy where (rw between x - 1000 and x + 1000) and (hw between y - 1000 and y + 1000)
mit Parametern?
Code:
select dx,dy where (rw between :x1 and :x2) and (hw between :y1 and :y2)
Delphi-Quellcode:
qry.ParamByName('x1').Value := x - 1000;
qry.ParamByName('x2').Value := x + 1000;
qry.ParamByName('y1').Value := y - 1000;
qry.ParamByName('y2').Value := y + 1000;
Um welche Datenmenge handelt es sich?

Index auf rw und hw vorhanden?

Statt TADODataSet mit TADOQuery arbeiten?

Liegt die DB lokal auf dem Rechner oder im Netz?

Mal mit den Werten von CursorLocation -> clUseServer / clUseClient spielen.

Ebenso mit CursorType.

Je nach Einstellung wird die gesamte Datenmenge erstmal zum Client "geschaufelt", was bei großen Datenmengen schon 'ne Weile dauern kann.

geosucher 8. Sep 2015 12:29

AW: SQL-Abfrage zu langsam
 
Hallo Stephan,

danke für die schnelle Antwort.
Die Access-DB liegt lokal vor. In der abgefragten Tabelle sind ca. 50000 Datensätze.
Im Programm werden ca. 500 Abfragen pro Lauf getätigt. (für 390 Abfragen braucht das Programm zur zeit 67 Sekunden)

Ich werde dann mal testen. Danke!

Roland

geosucher 8. Sep 2015 13:01

AW: SQL-Abfrage zu langsam
 
Umstellung auf SQL mit "between" und Indizes auf die Felder bringt eine Laufzeit von 23 Sekunden.
Umstellung auf CursorLocation auf clUseServer kommt auf 15 Sekunden
Umstellung des CursorType bringt nichts (bei Dynamic, OpenForwardOnly und Unspecified gibt es eine Fehlermeldung)

Gruß

Roland

nahpets 8. Sep 2015 13:11

AW: SQL-Abfrage zu langsam
 
Wieviele Änderungen gibt es in der Datenbank?
Wie groß ist die Datenbankdatei?

Eventuell hilft es, die Datenbank ab und an mal von Access reparieren zu lassen, sie wird dann auf eine erträgliche Dateigröße "geschrumpft". Vermutlich werden auch die Indizes neu erstellt.
Mir scheint (subjektiv) der Zugriff anschließend flüssiger vorzukommen.

Schau doch mal bitte nach, ob Du bei Dir die Komponente TJetEngine installiert hast. Sie ist in der JRO-Typlib zu finden.
Code:
// Typbib: C:\Programme\Gemeinsame Dateien\System\ado\msjro.dll (1)
// LIBID: {AC3B8B4C-B6CA-11D1-9F31-00C04FC29D52}
// LCID: 0
// Hilfedatei: C:\Programme\Gemeinsame Dateien\System\ado\msjro.chm
// Hilfe-String: Microsoft Jet and Replication Objects 2.6 Library
// DepndLst:
//   (1) v2.0 stdole, (C:\WINDOWS\system32\STDOLE2.TLB)
//   (2) v2.8 ADODB, (C:\Programme\Gemeinsame Dateien\System\ado\msado15.dll)
Mit 'nem Quelltext in der Art, könntest Du das Packen auch von Deinem Programm übernehmen lassen:
Delphi-Quellcode:
procedure TfmAccessDatenbankenPacken.PackMDB(sDatenbankname : String);
var
  sConnectionString : WideString;
  sdbTemp          : WideString;
  sdb              : WideString;
  sConDB           : WideString;
  sConDBTemp       : WideString;
begin
  Screen.Cursor    := crSQLWait;
  sConnectionString := 'Provider=Microsoft.Jet.OLEDB.4.0;User ID=Admin;Data Source=%s;'
                     + 'Mode=ReadWrite;Extended Properties="";'
                     + 'Jet OLEDB:System database="";'
                     + 'Jet OLEDB:Registry Path="";'
                     + 'Jet OLEDB:Database Password="";'
                     + 'Jet OLEDB:Engine Type=5;'
                     + 'Jet OLEDB:Database Locking Mode=1;'
                     + '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';
  sDB              := sDatenbankname;
  sDBTemp          := ChangeFileExt(sDB,'.tmp.mdb');
  sConDB           := Format(sConnectionString,[sDB]);
  sConDBTemp       := Format(sConnectionString,[sDBTemp]);
  Application.ProcessMessages;
  if FileExists(sdbTemp) then DeleteFile(sdbTemp);
  try
    je.CompactDatabase(sConDB,sConDBTemp);
    DeleteFile(sdb);
    RenameFile(sdbTemp, sDB);
  except
    on E : Exception do begin
      MessageDlg(E.Message,mtError,[mbOK],0);
    end;
  end;
  Screen.Cursor := crDefault;
  Application.ProcessMessages;
end;
Das ist aus 'nem Programm geklaut und muss nicht sofort so funktionieren, aber vielleicht kannst Du damit ja was anfangen.

geosucher 8. Sep 2015 13:46

AW: SQL-Abfrage zu langsam
 
Hallo Stephan,

die MDB-Datei hat 10,6 MB. In der Datenbank wird nicht mehr geändert, d.h. ich habe sie jetzt einmal komprimiert. Der Zugriff dauert jetzt noch 4 Sekunden - reicht voll und ganz. (Man soll aj auch noch merken, das das Programm arbeitet! :-D)

Danke!

Gruß

Roland


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:35 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