Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi TADODataset durchscrollen wird immer langsamer (https://www.delphipraxis.net/78865-tadodataset-durchscrollen-wird-immer-langsamer.html)

alzaimar 12. Okt 2006 11:11

Datenbank: Egal (ist aber MSSQL) • Zugriff über: ADO

TADODataset durchscrollen wird immer langsamer
 
Ich habe hier eine Tabelle mit 50.000 Datensätzen. Die wollte ich mal einlesen und durchscrollen (mit MyDataset.Next)...

Das wird ja immer langsamer, je weiter hinten man sich in der Tabelle befindet!

Für die ersten 1000 Zeilen werden in 16 ms durchgescrollt, die Zeilen 40000-41000 dagegen in 1218ms! Die Zunahme ist übrigens linear, pro 1000 Zeilen wird das Ganze um ca. 30ms langsamer.

Kann das jemand nachvollziehen? (Vermutlich) und kennt jemand einen Trick, wie man das umgehen kann?

Hier der Code (vielleicht werde ich ja einfach alt):
Delphi-Quellcode:
Procedure TForm1.Button1Click(Sender: TObject);
Var
  t: Cardinal;
  n : Integer;

Begin
  ADODataset1.Open;
  t := GetTickCount;
  n := 0;
  While Not ADODataset1.eof Do Begin
    inc(n);
    If n Mod 1000 = 0 Then Begin
      memo1.lines.add(format('%d %d', [n, GetTickCount - t]));
      t := GetTickCount;
    End;
    ADODataset1.Next;
  End;
End;
Da das Memo nur 44 mal angefasst wird, hab ich mir ein BeginUpdate/EndUpdate übrigens gespart. Bringt hier sowieso nix.

Bernhard Geyer 12. Okt 2006 13:33

Re: TADODataset durchscrollen wird immer langsamer
 
Wie schaut der Speicherverbrauch der Anwendung aus? Wieviel Speicher ist überhaupt vorhanden?
Welcher Curserlocation wird verwendet?
Wiviele Ergebnisspalten sind vorhanden (Größ, Anzahl Blobs, ...)?

alzaimar 12. Okt 2006 13:40

Re: TADODataset durchscrollen wird immer langsamer
 
10 Spalten, nur int und 2x datetime, Speicherverbrauch ist 15MB

shmia 12. Okt 2006 13:51

Re: TADODataset durchscrollen wird immer langsamer
 
Entscheidend ist die CursoLocation.
clUseServer: öffnen der Abfrage schnell, scrollen in der Datenmenge langsam
clUseClient: Öffnen der Abfrage dauert lange, da ALLE Datensätze vom Server zum Client transportiert werden, scrollen in der Datenmenge schnell

Bernhard Geyer 12. Okt 2006 14:08

Re: TADODataset durchscrollen wird immer langsamer
 
Zitat:

Zitat von shmia
Entscheidend ist die CursoLocation.
clUseServer: öffnen der Abfrage schnell, scrollen in der Datenmenge langsam
clUseClient: Öffnen der Abfrage dauert lange, da ALLE Datensätze vom Server zum Client transportiert werden, scrollen in der Datenmenge schnell

Das sollte sich aber nicht so graß auswirken (soweit ich das kenne) und nicht bei so popeligen 50.000 Datensätzen.

alzaimar 12. Okt 2006 14:16

Re: TADODataset durchscrollen wird immer langsamer
 
Gute Idee mit dem Cursor, das merke ich mir mal für später: Allerdings steht der cursor auf clUseClient.
Ich vermute mal, das die Implementierung des _Recordsets (MS) an der Stell suboptimal ist, und z.B. bei einem .Next immer von vorne anfängt zu suchen.

Ich erwähnte, das die ZUNAHME linear ist, das deutet aber auf ein quadratisches (polynomiales) Laufzeitverhalten hin. Ergo dürfte eine hirnkranke Implementierung wie oben wirklich der Grund sein.

Alles andere würde eine konstant langsame Ausführung bedeuten (Speicher, Cursorlocation etc.), weil eben pro Datensatz eine gewisse Verzögerung auftritt. Hier habe ich jedoch die Befürchtung, das daran liegt.

[EDIT]
Hab die Lösung:
Delphi-Quellcode:
Dataset.DisableControls;
Man lernt nie aus.

Hier der Code zum Beweis, das wirklich keine Datasource oder etwas anderes daran beteiligt war:
Delphi-Quellcode:
Var
  t: Cardinal;
  n: Integer;
  d: TAdoDataset;

Begin
  d := TAdoDataset.create(Nil);
  d.ConnectionString :=
    'FILE NAME=C:\Programme\Gemeinsame Dateien\System\Ole DB\Data Links\PVIP.UDL';
  d.CommandText := 'select * from Production';
  d.DisableControls; // So benötigt es 0.8sec, sonst 38sec !!!!
  t := GetTickCount;
  d.Open;
  n := 0;
  While Not d.eof Do Begin
    inc(n);
    If n Mod 1000 = 0 Then
      memo1.lines.add(format('%d %d', [n, GetTickCount - t]));
    d.Next;
  End;
  d.EnableControls;
End;
Ist das nicht bescheuert? Das DisableControls etwas bewirkt, obwohl überhaupt keine Controls da sind?

So, Microsoft ist unschuldig und Borland hat den bösen Buben.

Bernhard Geyer 12. Okt 2006 14:38

Re: TADODataset durchscrollen wird immer langsamer
 
Zitat:

Zitat von alzaimar
Ich vermute mal, das die Implementierung des _Recordsets (MS) an der Stell suboptimal ist, und z.B. bei einem .Next immer von vorne anfängt zu suchen.

Ich würde eher auf der Seite des Borland-Wrappers suchen. Ich verwende die nativen ADO-Interfaces auch bei großen MS SQL-Datenbanken und hatte bisher solch ein verhalten nicht.

Könntest Du ein kleines Testapp zusammenbasteln welche man auf die Northwind-Test-DB im MS SQL-server loslassen könnte um es an anderen Rechner testen zu können?

alzaimar 12. Okt 2006 14:43

Re: TADODataset durchscrollen wird immer langsamer
 
Hi Bernhard!

Hattest Recht, es war/ist Borland, siehe oben!


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