AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Select Count(*) vs. Select First 1
Thema durchsuchen
Ansicht
Themen-Optionen

Select Count(*) vs. Select First 1

Ein Thema von hoika · begonnen am 24. Mai 2017 · letzter Beitrag vom 27. Mai 2017
Antwort Antwort
Seite 2 von 3     12 3      
TigerLilly

Registriert seit: 24. Mai 2017
Ort: Wien, Österreich
1.211 Beiträge
 
Delphi 11 Alexandria
 
#11

AW: Select Count(*) vs. Select First 1

  Alt 24. Mai 2017, 11:40
Wenn(!) ein Full Table Scan notwendig ist, dann ist er das bei Count(*) Count(1) first 1 auch.
Es ist wirklich egal + es gibt kein Szenario, wo eines schneller wäre.

Und Achtung: wir reden hier von FB und nicht dBase.
  Mit Zitat antworten Zitat
jobo

Registriert seit: 29. Nov 2010
3.072 Beiträge
 
Delphi 2010 Enterprise
 
#12

AW: Select Count(*) vs. Select First 1

  Alt 24. Mai 2017, 12:38
Wieso sollte ein First in FB und ohne Angabe von Order by nicht schneller sein?
Ich habe selber schon geschrieben, dass es natürlich eine Frage der Implementierung ist, aber es würde sehr viel Sinn machen, nach der verlangten Anzahl Datensätze abzubrechen. Das kann count nicht.
Gruß, Jo
  Mit Zitat antworten Zitat
Poelser

Registriert seit: 21. Apr 2008
Ort: Europa
145 Beiträge
 
Delphi 10.4 Sydney
 
#13

AW: Select Count(*) vs. Select First 1

  Alt 24. Mai 2017, 13:00
Wenn FB (nutze ich allerdings nicht) einen SELECT FIRST 1 ohne Order By zulässt, dann ist das sicher schneller. Ich hatte mit ASA (welches eben Order By braucht) die schnellsten Ergebnisse mit SELECT 1 FIRST 1 ORDER BY 1. Das funktionierte rattenschnell, und zwingt auch dazu, die erste Spalte als PK-Spalte zu haben
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.276 Beiträge
 
Delphi 10.4 Sydney
 
#14

AW: Select Count(*) vs. Select First 1

  Alt 24. Mai 2017, 16:05
Hallo,
Zitat:
Adaptive Server Anywhere z.B. meckert beim First rum, dass das Ergebnis nicht deterministisch sein würde. Zurecht, denn die DB-Engine weiß ja nicht, dass mir der Inhalte des zurückgelieferten Datensatzes in diesem Fall egal ist.
Das habe ich gar nicht verstanden

Ich mache ein Select First 1 Id From Table1, das liefert mit den ersten Werte des Feldes Id, Reihenfolge ist hier auch egal.

Ich hatte irgendwo auch mal gelesen, dass Exists hier noch schneller ist:
Select 1 From RDB$DataBase Where Exists (Select First 1 Id From Table1)
Durch das Exists wird wohl noch schneller gesucht.

http://www.janus-software.com/fbmanu...=psql&topic=85

Ja, ich weiss er vergleicht mit Count(*).
Heiko
  Mit Zitat antworten Zitat
jobo

Registriert seit: 29. Nov 2010
3.072 Beiträge
 
Delphi 2010 Enterprise
 
#15

AW: Select Count(*) vs. Select First 1

  Alt 24. Mai 2017, 17:05
Ich mache ein Select First 1 Id From Table1, das liefert mit den ersten Werte des Feldes Id, Reihenfolge ist hier auch egal.

Ich hatte irgendwo auch mal gelesen, dass Exists hier noch schneller ist:
Select 1 From RDB$DataBase Where Exists (Select First 1 Id From Table1)
Durch das Exists wird wohl noch schneller gesucht.
Die Kernanmerkung (Unterschied zu FB FIRST) bei adaptive ist ja wohl, das adaptive das FIRST nur akzeptiert, wenn ein ORDER dabei ist. M.E. eine etwas schwache (oder pingelige) Implementierung. Wenn FB das FIRST ohne ORDER akzeptiert, tut es genau das, wozu es nach Deiner Anforderung in diesem THREAD eingesetzt wird.
(Würde man ein ORDER hinter das FIRST packen, käme vielleicht ein anderer Datensatz an erster Stelle, das Order zwingt aber genau wie das COUNT zu einer vollständigen Suche)
Es geht aber nur darum, ob 1 Datensatz EXISTiert.


Womit wir bei der EXIST Variante wären. Das Beispiel das Du anführst ist m.E. doppelt gemoppelt. Die Arbeit macht das FIRST Statement am Ende in Klammern. Das nochmal mit EXISTS abzufragen, bringt m.E. gar nichts. (Den Zusatzaufwand die Rückgabe von FIRST erneut zu prüfen, mal vernachlässigt, ansonsten wäre die Kombi EXISTS plus FIRST m.E. marginal sogar langsamer)
Gruß, Jo
  Mit Zitat antworten Zitat
TigerLilly

Registriert seit: 24. Mai 2017
Ort: Wien, Österreich
1.211 Beiträge
 
Delphi 11 Alexandria
 
#16

AW: Select Count(*) vs. Select First 1

  Alt 24. Mai 2017, 18:44
Das hat früher mal gestimmt, aber heute nicht mehr. Moderne query analyzer - und FireBird hat so was - erkennen diese Situationen und erzeugen idente execution plans.
Für ASA mag das nicht oder anders gelten, es implementiert den SQL92 Standard nicht vollständig.
Es gilt aber sicher für MS-SQL, Oracle, IB, FB.

Ob Tuning in einem solchen Bereich überhaupt Sinn hätte, wäre halt auch zu überlegen.
  Mit Zitat antworten Zitat
jobo

Registriert seit: 29. Nov 2010
3.072 Beiträge
 
Delphi 2010 Enterprise
 
#17

AW: Select Count(*) vs. Select First 1

  Alt 24. Mai 2017, 20:41
Na, wenn die das alle können, worüber reden wir dann?
Ein Optimizer kann m.E. nicht unterscheiden, ob ich über ein Count(*) nur wissen will, ob ein Datensatz da ist oder wirklich die Zahl haben will. Er kann nicht anders, als davon ausgehen, dass die korrekte Zahl benötigt wird.
Ob dann vorne dran noch ein Exists hängt oder was auch immer, geschenkt.

Neben der ganzen Tuning Diskussion bis jetzt, die sich "um die Spitze des Eisbergs" dreht, das Endergebnis von Count versus First usw. ist wahrscheinlich viel bedeutender, wie die Where Clause dahinter aussieht. Wenn das einigermaßen Index basiert durchläuft, ist es vermutlich irrelevant, ob ein Count=3 oder 15 rauskommt und ein First 1 statt dessen folglich 14 Indexzugriffe sparen täte.

Bei der Where Clause kann sich ein Optimizer prima austoben und ich behaupte mal, auch heute schadet notfalls etwas Analyse und ein paar Experimente nicht. Dass ein (auch moderner) Opensource Optimizer an MSSQL oder Oracle DB rankommt, wage ich allerdings zu bezweifeln.
Gruß, Jo
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#18

AW: Select Count(*) vs. Select First 1

  Alt 24. Mai 2017, 22:15
Hallo,
bei einer üblichen Performance-Analyse sehe ich mal wieder alten Code mit dem üblichen Select Count(*) .
Was für eine Performance?
Falls das Count wirklich auf dem Client stattfinden sollte, was ich für einige DBMS ausschließen kann, mißt Du hier eine fröhliche Summe von Einflußfaktoren. Wenn das Ergebnis nicht schnell genug zur Verfügung steht, kann alles mögliche hierauf Einfluß haben.
Wird das Count auf dem Server ausgeführt, hat man zumindest eine Näherung zu was die DB auf dem Server bei der augenblicklichen Konfiguration in der Lage ist.

Gruß
K-H

Zumindest bei den mir zur Verfügung stehenden Oracle-DB ist Count(*) immer sauschnell 10 Mio-Datensätze <3 sec
Was leider keine Aussage über die Datenbereitstellung anderer Abfragen erlaubt.
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
Benutzerbild von IBExpert
IBExpert

Registriert seit: 15. Mär 2005
679 Beiträge
 
FreePascal / Lazarus
 
#19

AW: Select Count(*) vs. Select First 1

  Alt 24. Mai 2017, 22:18
Ob Tuning in einem solchen Bereich überhaupt Sinn hätte, wäre halt auch zu überlegen.
Naja, das Tuning generell ist schon extrem hilfreich, je größer die DB um so eher bringt das was, zumindest
bezogen auf firebird.

Da ich aber die unterschiedlichen Varianten auch schon hier und da gehört hab, reizte es mich dann doch gerade
mal das mit geprüften Fakten zu bereichern.

Ergebnisse: Wenn eine "where xxx = ..." Bedingung mit 0 oder 1 Ergebnissen auf einem indizierten Feld benutzt wird, sind
alle Varianten (count(*), count(id), count(1), first 1) gleich schnell (siehe code beispiel unten)

Sobald die where Bedingung aber mehr als einen Datensatz liefert bzw Datensätze, die nicht auf einer Page
sind und man nur wissen muss das mindestens einer da ist oder nicht da ist, rechnet sich ein exists oder
insbesondere auch not exists sehr schnell, weil dann eben nicht weiter gesucht werden muss.

Die Datentypen selber haben aber auch indiziert erheblichen Einflus auf den speed

100000 randomsuche mit where indiziert auf bigint= ca 810 ms
100000 randomsuche mit where indiziert auf varchar(80) mit avg char_length 9= ca 1170 ms
100000 randomsuche mit where indiziert auf varchar(800) mit avg char_length 192= ca 4500 ms

Es gibt aber noch viel mehr Dinge, die man optimieren sollte, und teilweise sind die ganz
banal und erschreckend unlogisch, zB where Bedingung auf Feldern mit schlechter Selektvität,
Like in Prozeduren wenn parameter benutzt werden uvm.




Code:
execute block
as
declare variable i integer;
declare variable xx integer;
declare variable anz integer;
begin


  i=100000;
  while (i>0) do
  begin
    i=i-1;
    xx=rand()*100000;
    --v1  suchen über count(*)                828 ms  812 ms 828 ms
    --select count(*) from test where id=:xx into anz;
    --v2  suchen über count(id)               813ms 813ms 813ms
    --select count(*) from test where id=:xx into anz;
    --v3  suchen über count(1)                828 ms 828 ms 813ms
    --select count(1) from test where id=:xx into anz;
    --v4  suchen über first 1 id              797 ms 813 ms 812ms
    --select first 1 id from test where id=:xx into anz;
    --v5 suche über txt varchar(80) indiziert 1172 ms 1172 ms 1157 ms
    --select count(*) from test where txt='TXT2_'||:xx into anz;
    --v6 suche über txt2 varchar(800) indiziert 4531 ms 4421 ms 4422 ms
    --select count(*) from test where txt='TXT2_'||:xx||:xx||'TXT2_'||:xx||:xx||'TXT2_'||:xx||:xx||'TXT2_'||:xx||:xx||'TXT2_'||:xx||:xx||'TXT2_'||:xx||:xx||'TXT2_'||:xx||:xx||'TXT2_'||:xx||:xx||'TXT2_'||:xx||:xx||'TXT2_'||:xx||:xx||'TXT2_'||:xx||:xx||'TXT2_'||:xx||:xx||'TXT2_'||:xx||:xx into anz;
  end
end


/*
CREATE TABLE TEST (
    ID   BIGINT NOT NULL,
    TXT  VARCHAR(80),
    TXT2  VARCHAR(800)
);

ALTER TABLE TEST ADD PRIMARY KEY (ID);

CREATE INDEX TEST_IDX1 ON TEST (TXT);
CREATE INDEX TEST_IDX2 ON TEST (TXT2);



Daten in der Tabelle

ID;TXT;TXT2
0;"TXT2_0";"TXT2_00TXT2_00TXT2_00TXT2_00TXT2_00TXT2_00TXT2_00TXT2_00TXT2_00TXT2_00TXT2_00TXT2_00TXT2_00"
1;"TXT2_1";"TXT2_11TXT2_11TXT2_11TXT2_11TXT2_11TXT2_11TXT2_11TXT2_11TXT2_11TXT2_11TXT2_11TXT2_11TXT2_11"
2;"TXT2_2";"TXT2_22TXT2_22TXT2_22TXT2_22TXT2_22TXT2_22TXT2_22TXT2_22TXT2_22TXT2_22TXT2_22TXT2_22TXT2_22"
3;"TXT2_3";"TXT2_33TXT2_33TXT2_33TXT2_33TXT2_33TXT2_33TXT2_33TXT2_33TXT2_33TXT2_33TXT2_33TXT2_33TXT2_33"
4;"TXT2_4";"TXT2_44TXT2_44TXT2_44TXT2_44TXT2_44TXT2_44TXT2_44TXT2_44TXT2_44TXT2_44TXT2_44TXT2_44TXT2_44"
5;"TXT2_5";"TXT2_55TXT2_55TXT2_55TXT2_55TXT2_55TXT2_55TXT2_55TXT2_55TXT2_55TXT2_55TXT2_55TXT2_55TXT2_55"
6;"TXT2_6";"TXT2_66TXT2_66TXT2_66TXT2_66TXT2_66TXT2_66TXT2_66TXT2_66TXT2_66TXT2_66TXT2_66TXT2_66TXT2_66"
7;"TXT2_7";"TXT2_77TXT2_77TXT2_77TXT2_77TXT2_77TXT2_77TXT2_77TXT2_77TXT2_77TXT2_77TXT2_77TXT2_77TXT2_77"
8;"TXT2_8";"TXT2_88TXT2_88TXT2_88TXT2_88TXT2_88TXT2_88TXT2_88TXT2_88TXT2_88TXT2_88TXT2_88TXT2_88TXT2_88"
9;"TXT2_9";"TXT2_99TXT2_99TXT2_99TXT2_99TXT2_99TXT2_99TXT2_99TXT2_99TXT2_99TXT2_99TXT2_99TXT2_99TXT2_99"
10;"TXT2_10";"TXT2_1010TXT2_1010TXT2_1010TXT2_1010TXT2_1010TXT2_1010TXT2_1010TXT2_1010TXT2_1010TXT2_1010TXT2_1010TXT2_1010TXT2_1010"
11;"TXT2_11";"TXT2_1111TXT2_1111TXT2_1111TXT2_1111TXT2_1111TXT2_1111TXT2_1111TXT2_1111TXT2_1111TXT2_1111TXT2_1111TXT2_1111TXT2_1111"
....
insgesamt 100000 records
....
99.997;"TXT2_99997";"TXT2_9999799997TXT2_9999799997TXT2_9999799997TXT2_9999799997TXT2_9999799997TXT2_9999799997TXT2_9999799997TXT2_9999799997TXT2_9999799997TXT2_9999799997TXT2_9999799997TXT2_9999799997TXT2_9999799997"
99.998;"TXT2_99998";"TXT2_9999899998TXT2_9999899998TXT2_9999899998TXT2_9999899998TXT2_9999899998TXT2_9999899998TXT2_9999899998TXT2_9999899998TXT2_9999899998TXT2_9999899998TXT2_9999899998TXT2_9999899998TXT2_9999899998"
99.999;"TXT2_99999";"TXT2_9999999999TXT2_9999999999TXT2_9999999999TXT2_9999999999TXT2_9999999999TXT2_9999999999TXT2_9999999999TXT2_9999999999TXT2_9999999999TXT2_9999999999TXT2_9999999999TXT2_9999999999TXT2_9999999999"


*/
Holger Klemt
www.ibexpert.com - IBExpert GmbH
Oldenburger Str 233 - 26203 Wardenburg - Germany
IBExpert and Firebird Power Workshops jederzeit auch als Firmenschulung
  Mit Zitat antworten Zitat
Benutzerbild von IBExpert
IBExpert

Registriert seit: 15. Mär 2005
679 Beiträge
 
FreePascal / Lazarus
 
#20

AW: Select Count(*) vs. Select First 1

  Alt 24. Mai 2017, 22:34
Zumindest bei den mir zur Verfügung stehenden Oracle-DB ist Count(*) immer sauschnell 10 Mio-Datensätze <3 sec
Was leider keine Aussage über die Datenbereitstellung anderer Abfragen erlaubt.
Das ist an sich noch nichts wo man vor Erfurcht zusammenbrechen muss ...

Leider benutzen viele Kunden irgendwelche Server, die irgendwas sicher auch ganz schnell können,
aber für Firebird kompletter Schrott sind und trotzdem sauteuer.

Wenn man die dann mit sauteuren uund hochoptimierten Oracle oder MSSQL Servern vergleicht,
kommt da nichts bei raus. Und frag am besten weder Dell, HP noch Lenovo nach geeigneter
Firebird Hardware, die Systemhäuser stellen da nur teuren Quatsch zusammen.

Diesen Test hab ich gerade auf einer Kunden DB gemacht, count(*) für ca 3mio Datensätze
in ca. 0,6 Sekunden

Die Serverhardware ist von uns geliefert, kostet mit 1TB ca 3500 € und schafft
einen IBExpert Firebird Benchmark von >=500% Driveindex und >=300% CPU Index
und ist transaktionsecht live auf einer zweiten baugleichen Maschine repliziert.

Vermutlich ab nächste Woche bieten wir die auch wieder außerhalb von Kundenprojekten an
und im Herbst machen wir damit vermutlich mal wieder eine Roadshow.


Code:

query:

Select count(*) from brpst

COUNT
2979487

Plan
PLAN (BRPST NATURAL)

------ Performance info ------
Prepare time = 16ms
Execute time = 625ms
Avg fetch time = 625,00 ms
Current memory = 1.171.921.280
Max memory = 0
Memory buffers = 40.000
Reads from disk to cache = 6.955
Writes from cache to disk = 2
Fetches from cache = 0
Holger Klemt
www.ibexpert.com - IBExpert GmbH
Oldenburger Str 233 - 26203 Wardenburg - Germany
IBExpert and Firebird Power Workshops jederzeit auch als Firmenschulung
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 3     12 3      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:30 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