Delphi-PRAXiS
Seite 3 von 6     123 45     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi [FB 2.1] Schnelle Alternative zu Count(*) ? (https://www.delphipraxis.net/133871-%5Bfb-2-1%5D-schnelle-alternative-zu-count-%2A.html)

dataspider 11. Mai 2009 18:47

Re: [FB 2.1] Schnelle Alternative zu Count(*) ?
 
Zitat:

Zitat von mkinzler
Es müssen nur die Einträge im Index gezählt werden, was etwas schneller sein sollte

Ich denke nicht, dass die DB - Entwickler für Count nur den Index durchlaufen.
Das Verfahren würde wirklich nur bei einem einfachen Count funktionieren.
Aber das ist jetzt wohl Spekulation und vielleicht hast du ja recht.
Ich habe mit IBExpert das Verhalten mal verglichen (bei ca. 700.000 Records).
Die Zeiten sind identisch, wenn ich select count(PK) from table bzw. select count(pk) from table where pk > 0 nehme.
Der Index wird im 2. Statement benutzt.

Frank

alzaimar 11. Mai 2009 18:49

Re: [FB 2.1] Schnelle Alternative zu Count(*) ?
 
Zitat:

Zitat von dataspider
Wie soll ein Index beim Zählen aller Datensätze behilflich sein?

Oh, das ist ganz einfach:
Ohne Index muss man wirklich alle Zeilen durchlaufen (oder die geheime Tabelle mit den Metadaten finden).
Mit Index zähle ich nur die Anzahl der B-Tree-Seiten und multipliziere sie mit der Größe eines Indexelementes.
B-Tree-Seiten von Index-Strukturen wissen zudem, wie viele Elemente sie enthalten. Ich kenne zwar die FB-Implementierung nicht, kann mir aber nicht vorstellen, das FB bei B-Trees andere Wege schreitet, als der gängige und bewährte Standard. Der Weg über die B-Tree-Seiten macht also das Zählen um einen konstanten Faktor schneller (z.B. f=2000 für einen INTEGER-PK), denn ich muss nicht N Zeilen zählen, sondern nur N/f Seiten.

Weiterhin haben Indexstatistiken Informationen über die Gesamtanzahl der Einträge, sowie mindestens die Anzahl der unterschiedlichen Einträge (häufig noch zusätzliche Informationen), um beim Optimieren bzw. Erstellen des Queryplans den besser strukturierten Index zu bevorzugen.

Es müsste also theoretisch gehen.

Allerdings kann ich mir nicht vorstellen, einen solchen Sonderfall in der Erstellung des Queryplans für ein 'COUNT(*)' einzubauen. Kein TPC-Benchmark würde das würdigen.

Dann doch lieber die geheimen Metatabellen zugänglich machen. Irgendwo muss doch einfach stehen, wieviel Records in dieser Tabelle stehen. Ob nun mit oder ohne PK. Dammich, verdammt :wall: :stupid:

PS: Ich bekomm tatsächlich beim Programmstart ab und an ein Deadlock Problem. Einmal. Immer am Anfang. :gruebel: Muss an mir liegen. Ich schau mir das morgen nochmal an.

mkinzler 11. Mai 2009 18:51

Re: [FB 2.1] Schnelle Alternative zu Count(*) ?
 
Zitat:

Die Zeiten sind identisch, wenn ich select count(PK) from table bzw. select count(pk) from table where pk > 0 nehme.
Und bei Count(*)?

dataspider 11. Mai 2009 19:00

Re: [FB 2.1] Schnelle Alternative zu Count(*) ?
 
Zitat:

Zitat von mkinzler
Und bei Count(*)?

Ups... scheint doch schneller zu sein... :oops:

Frank

[EDIT]
Hmmm, habe jetzt noch mal count(*) gemacht, ist jetzt auch so schnell.
Wahrscheinlich hält FB die Daten auch nach einem Disconnect noch länger im Cache.
[/EDIT]

Chemiker 11. Mai 2009 19:00

Re: [FB 2.1] Schnelle Alternative zu Count(*) ?
 
Hallo alzimar,

könnte man nicht den aktuellen Generator-Wert auslesen und die gelöschten Datensätze davon abziehen?

Bis bald Chemiker

mkinzler 11. Mai 2009 19:02

Re: [FB 2.1] Schnelle Alternative zu Count(*) ?
 
Zitat:

könnte man nicht den aktuellen Generator-Wert auslesen und die gelöschten Datensätze davon abziehen?
Und wie bekommst du die gelöschten raus?

Chemiker 11. Mai 2009 19:07

Re: [FB 2.1] Schnelle Alternative zu Count(*) ?
 
Hallo mkinzler,

z.B.: 2 Generator mitlaufen lassen für gelöschte Datensätze, oder in einem anderen Bereich des 1 Generators.

Ist nur so eine Idee.

Bis bald Chemiker

mjustin 11. Mai 2009 19:31

Re: [FB 2.1] Schnelle Alternative zu Count(*) ?
 
Zitat:

Zitat von Chemiker
Hallo mkinzler,

z.B.: 2 Generator mitlaufen lassen für gelöschte Datensätze, oder in einem anderen Bereich des 1 Generators.

Ist nur so eine Idee.

Bis bald Chemiker

Hat einen Haken: Generatoren laufen ausserhalb von Transaktionen. Wenn also ein Satz gelöscht wird, wird der neue Generatorwert sofort für alle Transaktionen sichtbar - also schon vor dem Commit. Wenn die Transaktion dann ein Rollback macht, und damit das Löschen des Satzes (im Before Delete oder After Delete Trigger) verwirft, steht der falsche Wert noch im Generator. Auch bei After Delete ist die Transaktion noch nicht unbedingt committed.

Chemiker 11. Mai 2009 20:30

Re: [FB 2.1] Schnelle Alternative zu Count(*) ?
 
Hallo mjustin,

und wie ist das bei COUNT?

Bis bald Chemiker

mjustin 11. Mai 2009 20:50

Re: [FB 2.1] Schnelle Alternative zu Count(*) ?
 
Zitat:

Zitat von Chemiker
Hallo mjustin,

und wie ist das bei COUNT?

Bis bald Chemiker

Count läuft innerhalb der Transaktion. Verschiedene Transaktionen können daher zu unterschiedlichen Ergebnissen (Anzahl Sätze) kommen. 'Die' Anzahl Sätze ist also relativ zur Transaktion zu sehen. Wenn ein Programm sich nur mit der Datenbank verbindet, eine Anfrage mit Select Count(*) macht und dann die Verbindung trennt, ist die erhaltene Information in der nächsten Nanosekunde natürlich schon wieder wertlos. Aber das Problem ist ja, wenn ich den Thread richtig lese, die lange Ausführungszeit eines Count(*).



Wie wäre es, z.B. anhand eines Zeitstempels (Datum der Satzanlage) nur die aktuellen Sätze abzufragen?

Also wenn z.B. die Daten bis April 2009 sich nicht mehr allzusehr ändern, macht man ein

Select count(*) from tabelle where creationdate >= '01.05.2009'

Und addiert eine bereits bekannte Satzanzahl für alle davor liegenden Sätze auf.


Oder man geht etwas weg von der Datenbank, erzeugt in der Anwendung eine 'Satz erzeugt' oder 'Satz gelöscht' Message an einen zentralen Prozess (Application Server, simplen Telnetserver, whatever) und dieser sammelt die Messages und aktualisiert die Anzahl, entweder in einer Datenbanktabelle die nur einen Satz enthält, oder indem er in einer Antwortmessage die aktuelle Zahl zurückliefert.


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:56 Uhr.
Seite 3 von 6     123 45     Letzte »    

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