Announcement

Collapse
No announcement yet.

Langsame Query (beim ersten Mal)

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Langsame Query (beim ersten Mal)

    Hallo

    Ich programmierte ein Programm mit Delphi 6, um mittels ADO auf eine Access 97 DB zuzugreifen.

    Die Anwendung ist eine MDI Application. Im MDI-Child Form besteht im wesentlichen aus der ADOQuery und einer DBGrid Komponente.

    Das komische ist jetzt, dass für das erste MDI-Child fast 2 Sekunden vergehen, bis es erscheint. Bei allen weiteren geht es dann nur noch 0.2 Sekunden. Ich mache dann alle Forms wieder zu und öffne wieder eines und wieder vergehen 2 Sekunden.

    Kann mir bitte jemand erklären, wieso das so ist? Was kann man dagegen machen? Denn bei komplexeren Fenstern mit mehreren Grids braucht das öffnen zu lange, dass niemand damit arbeiten kann.

    Die Verbindung zur Datenbank macht ich schon beim Programmstart und nicht erst beim öffnen das MDI-Child.

    Ich machte jetzt folgenden Trick: Ich öffne jetzt schon im MDI-Form Fenster eine ADOQuery mit der selben Select Anweisung und mit dem Zusatz WHERE (false=true) und lasse diese Query während der ganzen Zeit offen. Damit wird auch das erste MDI-Child Form schnell geöffnet. Aber das kann ja auch nicht die Lösung sein: Erstens muss ich jede Query zweimal machen und zweitens braucht so das Programm länger, bis es gestartet ist.

    So, ich hoffe, das diese Informationen ausreichen, damit ihr mir helfen könnt.

    Gruss
    Markus

  • #2
    Hallo,

    &gt;...dass für das erste MDI-Child fast 2 Sekunden vergehen...<br>
    &gt;Kann mir bitte jemand erklären, wieso das so ist?

    eine ACCESS-Datenbank ist keine SQL-Datenbank, so dass der eingebundene Provider (Microsoft Jet Engine) die SQL-Fähigkeit nur simulieren muss. Ich gehe einmal davon aus, dass die ADO-Komponenten für die Eigenschaft CursorLocation den Wert <b>clUseClient</b> verwenden. Damit erhält die Jet Engine den Auftrag, alle Datensätze beim ersten Öffnen der Tabelle aus der MDB auszulesen und im eigenen Arbeitsspeicher zu puffern (also ein doppelter Puffer).

    Normalerweise wäre die Kombination von <b>clUseServer</b> (CursorLocation) und <b>cmdTableDirect</b> (CommandType) für ACCESS-Datenbanken richtig, denn dann kann TADODataSet die ACCESS-Tabellen nativ (also im Datensatzzeiger-orientierten Modus) öffnen, so dass die doppelte Pufferung entfällt. Anstelle von WHERE sorgt dann ein Filter für die Einschränkung der sichtbaren Datensätze.

    Wenn es unbedingt bei clUseClient bleiben soll, wäre das asynchrone Laden der Daten über <b>ExecuteOptions:= [eoAsyncFetchNonBlocking]</b> ein Ausweg. ADO lädt die Daten im Hintergrund, ohne die Benutzeroberfläche einzufrieren.
    &#10

    Comment


    • #3
      Vielen Dank für die promte Anwort, aber...

      Nein, der CursorLocation ist schon auf clUseServer.
      Das Problem liegt wahrscheinlich beim Zugriff auf die Access-DB-Datei.
      Ich glaube, dass die erste Query auch gleich noch die 'Initialisierung' der DB Datei macht. Mache ich diese erste Query wieder zu und öffne sich wieder, geht es wieder so lange. Lasse ich aber die erste Query offen und öffne noch eine zweite, dann ist die zweite Query (und alle weiteren) viel schneller.

      Ich habe mal unten eine relativ grosse SQL Abfrage hingeschrieben:

      SELECT MRapport.*, [MRa_AStd]*[MRa_Ansatz] As ATotal, [MRa_MStd]*[MRa_Ansatz] As MTotal, Art_ArtNr, Art_Bez, Art_Einheit, Dok_Nr, Dok_Bez, Dok_Closed, [All_Name] & " " & [All_Vorname] AS Mitarbeiter
      FROM ((MRapport LEFT JOIN `P:\Test\adressen.mdb`.Adr_Allgemein Adr_Allgemein ON MRapport.MRa_MitNr = Adr_Allgemein.All_Nr) LEFT JOIN `P:\Test\dokumente.mdb`.Dok Dok ON MRapport.MRa_AufNr = Dok.Dok_DokNr) LEFT JOIN `P:\Test\artikel.mdb`.Artikel Artikel ON MRapport.MRa_ArtNr = Artikel.Art_ID;

      Wie man sieht, holt sie noch Daten aus drei weiteren Access Dateien.
      Sind alle Dateien auf einem Server ausgelagert, braucht die erste Query ca 2 Sekunden und alle weiteren nur noch 0.2 Sekunden (bei einem 10MBit Netzwerk). Habe ich alle Dateien auf meinem lokalen PC, dann verkürzt sich die Zeit auf 0.2 Sekunden bei der ersten Abfrage und noch ca. 0.12 Sekunden bei allen andern. Ach ja, das Resultat dieser Abfrage liefert 16000 Records.

      Wenn ich jetzt für jede dieser zusätzlichen Access Dateien noch ein ADOConnection erstelle und öffne, dann wird es erste Mal auch nicht schneller. Und wenn ich dazu noch je eine ADOQuery (SELECT All_Nr
      FROM Adr_Allgemein WHERE (1=0) öffne, ebenso nicht.

      Erst wenn ich direkt nach dem starten eine ADOConnection und vier ADOQuerys, mit der SQL Anweisung:

      SELECT All_Nr
      FROM `P:\Test\adressen.mdb`.Adr_Allgemein Adr_Allgemein
      WHERE (1=0);

      zuerst öffne und dann die eigentliche SQL Anweisung öffne, ist diese auch beim ersten mal schnell.

      So, jetzt hoffe ich, dass jemand diese Erklärung verstanden hat.
      Ansonsten würde ich gerne mal ein kleines Beispielprogramm zumailen. Wer also interessiert ist daran, soll mir doch seine E-mail Adresse geben.

      Dank

      Comment


      • #4
        Hallo,

        &gt;..Erst wenn ich direkt nach dem starten eine ADOConnection und vier ADOQuerys..ist diese auch beim ersten mal schnell.

        welche Betriebssysteme verwenden die Clients und der File-Server? Was passiert, wenn das Programm gleich beim Start eine beliebige Datei (Bsp: test.txt) auf "P:\TEST" öffnet? Ändert sich das Verhalten beim ersten Zugriff auf ADO

        Comment


        • #5
          Server ist NT 4
          Und Clients habe eich Win 2000 und Win 98.

          Und zur letzten Frage: nein

          Comment

          Working...
          X