Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Speicherfresser : TQuery und MSSQL (https://www.delphipraxis.net/85412-speicherfresser-tquery-und-mssql.html)

2_daniel 30. Jan 2007 14:07

Datenbank: MSSQL Server • Version: 2005 • Zugriff über: BDE / ODBC

Speicherfresser : TQuery und MSSQL
 
Hallo an alle,
ich habe folgendes Problem festgestellt:

1. Query öffnen ( select Feld1,..., Feldn from Tabelle ) => dieser Select bringt viele Datensätze zurück( über 15 tausend )

2.Query öffnen( select id from Tabelle2). also diese Query hat mit der 1. nicht zu tun. Auch wenn der SQL-Statement,, der 2. Query, falsch ist passiert folgendes:

die 1. Query lädt sich alle Daten vom server herunter. Dies bewirkt dass der Speicher enorm in der Höhe geht. Und dann kommt die schöne Meldung: Not enough Memory for this operation. Feierabend.

Falls die 2. Query einen Tippfehler hat, kommt die MEldung: SQL Fehler erst nachdem alle Daten der 1. Query "heruntergeladen" wurden.


Als DB-Server habe ich einen MSSQl 2005er im einsatz.
Komponenten: TQuery
Ausser der 2 Querys ist keine weitere Komponente im Spiel. DAfür habe ich mir einen dummy-Projekt erstellt,um Seiteneffekte zu vermeiden.


Hat jemand einen Tipp wo/wie das lösen ist??

Auch wichtig: unter ASA( iAnywhere) passiert sowas nicht....

gruss & besten Dank ,
daniel

Pfoto 30. Jan 2007 14:29

Re: Speicherfresser : TQuery und MSSQL
 
Hallo Daniel!

Erstmal die Frage:
Ist es denn nötig, so viele Datensätze zurückzuliefern?
Wenn nicht, dann grenze doch deine Abfrage etwas ein,
notfalls mit dem Statement SELECT * TOP 500 (sowas in der Art)

Da die Querys idR. hinereinander ausgeführt werden,
kommt ein evtl. Fehler bei der 2. Query natürlich immer etwas
verzögert.


Aber wenn du wirklich alle Tabellen-Daten brauchst, könntest
du stattdessen besser eine TTable-Komponente nehmen (wenn
du keine Joins über mehrere Tabellen machen musst)

Gruß
Pfoto

mkinzler 30. Jan 2007 14:35

Re: Speicherfresser : TQuery und MSSQL
 
Warum geifst du nicht direkt auf den DB-Server zu und bedienst dich gleich 2 veralteter Techniken?

hoika 30. Jan 2007 14:36

Re: Speicherfresser : TQuery und MSSQL
 
Hallo,

Query.UniDirectional auf True setzen,
dann chached die Bde die Einträge nicht lokal.


Heiko

2_daniel 30. Jan 2007 15:10

Re: Speicherfresser : TQuery und MSSQL
 
Zitat:

Zitat von hoika
Hallo,

Query.UniDirectional auf True setzen,
dann chached die Bde die Einträge nicht lokal.
Heiko

...dies ist Teils einer Datenverwaltung, darum fällt Unidirectional aus.



Zitat:

Zitat von mkinzler
Warum geifst du nicht direkt auf den DB-Server zu und bedienst dich gleich 2 veralteter Techniken?

..weil ich noch eine ASA( iAnywhere) DB unterstützen muss, und mom. alles npch über BDE geht. Tja, irgendwann wirds wohl soweit sein....
Zitat:

Zitat von Pfoto
Hallo Daniel!

Erstmal die Frage:
Ist es denn nötig, so viele Datensätze zurückzuliefern?
Wenn nicht, dann grenze doch deine Abfrage etwas ein,
notfalls mit dem Statement SELECT * TOP 500 (sowas in der Art)

Da die Querys idR. hinereinander ausgeführt werden,
kommt ein evtl. Fehler bei der 2. Query natürlich immer etwas
verzögert.


Aber wenn du wirklich alle Tabellen-Daten brauchst, könntest
du stattdessen besser eine TTable-Komponente nehmen (wenn
du keine Joins über mehrere Tabellen machen musst)

Gruß
Pfoto

das mit 2 Queries hintereinander ist nur wann die Speicherverwaltung anfängt zu spinnen. IdR ist es so, dass eine Query die Daten in einem Grid anzeigt, und über eine Table/DB-Sensitive Felder die Daten verwaltet werden.hier kann es passieren dass eine Zusatzquery gefuert wird...unda dann geht der Speicher in die Höhe....und sowas sieht dann nicht schön aus.

Select Topx wird ( noch nicht benutzt) weil über alle Daten noch eine Suchfunktion läuft...und die würde dann Sätze nicht finden, wenn Topx angewendet wird....oder man müsste die umbauen....FAKT: Topx wird noch nicht benutzt. dies ist aber eine Überlegung wert. DANKE!!


TTables auf viele Datensätzen...braucht eine Ewigkeit bis die geöffnet wird. Also eine schlechtere Alternative.


Meinproblem bleibt weiterhini: WIESO holt sich der SQL-Server die Daten lokal, wenn ein anderes Statement einer anderen Query gestertet wird. Liegt es am MSSQL allgemein, oder ist es eine "gelungene" Einstellung auf meiner Machine( aufm anderen Rechner passiert dasgleiche..also.... )

danke auch für die schnellen Antworten... Problem bleibt weiterhin vorhanen :(

gruss
daniel

NormanNG 30. Jan 2007 15:32

Re: Speicherfresser : TQuery und MSSQL
 
Hi,

wie bingst du denn die Abfrage in die Query?
Wenn du jedesmal das selbe Query-Objekt verwendest und nur die neue Abfrage mit SQL.Add(...) hinzufügst, dann bleibt die erste Abfrage weiterhin drin stehen. Versuchs mal mit SQL.Clear dazwischen.

mkinzler 30. Jan 2007 15:38

Re: Speicherfresser : TQuery und MSSQL
 
Zitat:

Versuchs mal mit SQL.Clear dazwischen.
Oder gleich der Eigenschaft Text zuweisen.

2_daniel 30. Jan 2007 16:15

Re: Speicherfresser : TQuery und MSSQL
 
Zitat:

Zitat von NormanNG
Hi,

wie bingst du denn die Abfrage in die Query?
Wenn du jedesmal das selbe Query-Objekt verwendest und nur die neue Abfrage mit SQL.Add(...) hinzufügst, dann bleibt die erste Abfrage weiterhin drin stehen. Versuchs mal mit SQL.Clear dazwischen.

...dass wird doch immer clean ausgeführt ...mit .Text := '...';

das Problem liegt NICHT daran, dass die Queries nicht laufen, sondern dass der Speicher extrem in die Höhe geht( siehe Problembeschreibung ).

gruss,
daniel

shmia 30. Jan 2007 16:43

Re: Speicherfresser : TQuery und MSSQL
 
Grundsätzlich funktionieren Abfragen so:
1.) der Client sendet seine SQL-Anweisung an den Server
2.) der Server führt die SQL-Anweisung aus
3.) wenn die SQL-Anweisung ein Resultset (alles was mit SELECT beginnt) hat, wird die komplette Datenmenge an den Client übertragen
4.) der Server ist fertig und der Client speichert das gesamte Resultset zwischen
Das nennt man "client seitigen Cursor"

Es gibt auch "serverseitige Cursor"
3.) der Server speichert das gesamte Resultset zwischen und gibt auf Anforderung immer nur Teile an den Client.
4.) wenn der Client das Resultset schliesst, darf der Server das Resultset freigeben
Wie man sieht, ist bei dieser Variante der Speicherbedarf vom Client auf den Server übergegangen.
Bei vielen Clients droht hier Serverüberlastung.

Wenn du also ein Speicherproblem auf dem Client hast, solltest du
1.) die Anzahl der Spalten reduzieren
2.) die Anzahl der Datensätze reduzieren
3.) Arbeit vom Client zur Server delegieren (Stored Procedures)
4.) Hardware aufrüsten
Andere Lösungen gibt es nicht.

hoika 31. Jan 2007 07:14

Re: Speicherfresser : TQuery und MSSQL
 
Hallo,

genau so sieht es aus.

"Suchfunktion über alle Datensätze" -> SP oder einfache Query (Select Sum)

Mit Unidirectional=False cachet die Bde alle geladenen Datensätze,
damit man z.B. mit Prior einen Datensatz zurück gehen kann.

Ich hatte auch mal was von nem Speicherleck der Bde gehört,
Abhilfe war damals das explizute Prepare / UnPrepare gewesen.


Heiko

2_daniel 1. Feb 2007 22:49

Re: Speicherfresser : TQuery und MSSQL
 
danke für die Feedbacks....ich werde es morgen früh ausprobieren.

hoffe dass es mit prepare/unpreapre erstmal eine Lösung wird.....



gruss,
daniel

2_daniel 2. Feb 2007 14:19

Re: Speicherfresser : TQuery und MSSQL
 
...hmmm prepare / unprepare zeigt keine wirkung.

hier nochmal/ anders ausgedrückt meine Problem...

1. query (query1) wird gestartet -> ist blitzschnell fertig (obwohl es um ein große datenmenge geht)

2. query (query2) wird irgendwann später gestartet (von hand über einen button)

in dem moment wo query2.open ausgeführt wird, wird durch query1 der speicher voll gemacht.
erst wenn query 1 dann irgendwann fertig ist, wird query2 ausgeführt.


...und alles nur im Verbindung mit MSSQL Server


gruss,
daniel

hoika 3. Feb 2007 07:46

Re: Speicherfresser : TQuery und MSSQL
 
Hallo,

das Query1.Open ist wohl nur deshalb so schnell fertig,
weil du nur das Open machst (?).
Das wird auf dem Server gemacht und erzeugt erst mal keinen Netzwerk-Traffic.

Mach mal direkt hinter dem Query1.Open ein Query1.RecordCoun oder Query1.Last.
Das lädt alle Daten herunter.
Dann solltest du das Speicherproblem auch haben.

Warum muss UniDirectional auf False stehen ?.
Reicht denn das einfache Laden dieser Daten in der "Order By"-Reihenfolge nicht ?


Heiko

2_daniel 14. Feb 2007 17:32

Re: Speicherfresser : TQuery und MSSQL
 
Hallo an alle,

danke erstmal für die vielen Antworten.

die Lösung die ich implementiert habe sieht folgender massen aus( speicherauslastung "normal" ) :

die 1. Query lädt nur die absolut notwendigsten Felder , dh "Select * from..." ist zwar allgemein, aber extrem speicherfressend.

und ein "Select Top x ... from ...." ist auch vorhanden.


gruss,
daniel


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