AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Vorhandensein eines Records prüfen
Thema durchsuchen
Ansicht
Themen-Optionen

Vorhandensein eines Records prüfen

Ein Thema von hoika · begonnen am 13. Jul 2017 · letzter Beitrag vom 14. Jul 2017
Antwort Antwort
Seite 1 von 2  1 2      
hoika

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

Vorhandensein eines Records prüfen

  Alt 13. Jul 2017, 08:35
Datenbank: FB • Version: 2.01 • Zugriff über: egal
Hallo,
oft muss ich prüfen, ob mindestens ein Record in einer Tabelle vorhanden ist

Version 1
die klassische Vorgehensweise: Select Count(*)

Version 2
wir nutzen "neue" FB-Funktionen
Select First 1 Wert From Tabelle

Version 3
tricky Ausnutzung von Firebird-Besonderheiten beim Exists
Select 1 From RDB$DataBase Where Exists(Select Wert From Tabelle)
Wobei das durch Version 2 mit dem First ja jetzt wohl gegenstandslos ist


Das Where habe ich weggelassen, auf dem Where-Feld ist auf jeden Fall ein Index.
Die Suche läuft also auf jeden Fall über einen Index
(viele Datensätze, gute Selektivität des Suchfeldes)

Mein Gefühl sagt mir, dass Version 2 die schnellste Variante ist.
Der Query-Plan ist aber bei V1 und V2 der gleiche.


Was meint Ihr?
Heiko
  Mit Zitat antworten Zitat
Benutzerbild von Neutral General
Neutral General

Registriert seit: 16. Jan 2004
Ort: Bendorf
5.219 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#2

AW: Vorhandensein eines Records prüfen

  Alt 13. Jul 2017, 09:22
Wenn der Query-Plan der gleiche ist, dann kann das eine nicht schneller sein als das andere.
Michael
"Programmers talk about software development on weekends, vacations, and over meals not because they lack imagination,
but because their imagination reveals worlds that others cannot see."
  Mit Zitat antworten Zitat
Benutzerbild von DelphiBandit
DelphiBandit

Registriert seit: 19. Feb 2007
Ort: In der Lüneburger Heide
165 Beiträge
 
Delphi 10.4 Sydney
 
#3

AW: Vorhandensein eines Records prüfen

  Alt 13. Jul 2017, 09:37
Wenn ich das richtig verstanden habe, dann interessiert Dich nur, ob ein/mehrere Datensätze da sind oder die Tabelle noch leer ist. Korrekt?

Hätte dazu folgenden Hack in meinen Firebird-Bookmarks gefunden. Ist rasend schnell, setzt aber eingeschaltete Statistics und einen Primärindex voraus. Alles was 0 liefert wurde in den Statistics bisher noch nicht angefasst.

Quelle: http://www.firebirdfaq.org/faq5/

Wobei es nicht ausgeschlossen ist, dass die Datenbank-Engine solch Konstrukte vielleicht auch selbst intern nutzt

Code:
SELECT RDB$RELATIONS.RDB$RELATION_NAME,
       CASE
         WHEN RDB$INDICES.RDB$STATISTICS = 0 THEN 0
         ELSE CAST(1 / RDB$INDICES.RDB$STATISTICS AS INTEGER)
       END
  FROM RDB$RELATIONS
  LEFT JOIN RDB$RELATION_CONSTRAINTS
       ON RDB$RELATIONS.RDB$RELATION_NAME = RDB$RELATION_CONSTRAINTS.RDB$RELATION_NAME
       AND RDB$CONSTRAINT_TYPE = 'PRIMARY KEY'
  LEFT JOIN RDB$INDICES
       ON RDB$RELATION_CONSTRAINTS.RDB$INDEX_NAME = RDB$INDICES.RDB$INDEX_NAME
WHERE RDB$VIEW_BLR IS NULL AND RDB$RELATION_ID >= 128
AND  RDB$RELATIONS.RDB$RELATION_NAME = 'HIER DEN TABELLENNAMEN'
ORDER BY 1;
Carsten

Geändert von DelphiBandit (13. Jul 2017 um 09:39 Uhr)
  Mit Zitat antworten Zitat
hoika

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

AW: Vorhandensein eines Records prüfen

  Alt 13. Jul 2017, 09:43
Hallo,
setzt aber eingeschaltete Statistics und einen Primärindex voraus
Was sind denn ausgeschaltete Statistics?

Wobei es nicht ausgeschlossen ist, dass die Datenbank-Engine solch Konstrukte vielleicht auch selbst intern nutzt
Schon möglich

Wenn der Query-Plan der gleiche ist, dann kann das eine nicht schneller sein als das andere.
Doch, wenn ich ein Count(*) machen, muss er alle passenden Einträge zusammenzählen,
bei First 1 kann die Indexsuche nach dem ersten Treffer abbrechen.
Der Query-Plan ist aber trotzdem der gleiche.
Heiko

Geändert von hoika (13. Jul 2017 um 09:46 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von DelphiBandit
DelphiBandit

Registriert seit: 19. Feb 2007
Ort: In der Lüneburger Heide
165 Beiträge
 
Delphi 10.4 Sydney
 
#5

AW: Vorhandensein eines Records prüfen

  Alt 13. Jul 2017, 09:48
OK. Etwas im Wort vergriffen, aktuelle/aktualisierte Statistics trifft es besser.

Kannst ja einfach mal mit dem SQL und einer vollen Tabelle testen, ob es noch ein Quentchen schneller ist als mit FIRST 1.
Carsten
  Mit Zitat antworten Zitat
Benutzerbild von Jasocul
Jasocul

Registriert seit: 22. Sep 2004
Ort: Delmenhorst
1.355 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: Vorhandensein eines Records prüfen

  Alt 13. Jul 2017, 09:49
Interessant ist es eigentlich nur für Abfragen auf Tabellen mit großen Datenmengen.
Bei leeren Datenmengen ist der Unterschied normalerweise zu vernachlässigen. Das dürfte sich in allen Fällen im Millisekunden-Bereich bewegen.

Ich habe mal alle drei Verfahren auf MS-SQL getestet. Die Tabelle enthält über 40 Mio Datensätze.

Select Count(*) ist indiskutabel (Testserver: 50 Sekunden. Live-Server knapp 3 Sekunden).

Die beiden anderen Varianten haben keinen messbaren Unterschied und befinden sich im einstelligen Millisekunden-Bereich.

Der Hack von DelphiBandit funktioniert nur bei eingeschalteter Statistik, wie er schon selbst geschrieben hat. Meines Wissens kann das Ergebnis trotzdem falsch sein, da die Statistics nicht permanent aktualisiert werden.
Peter

Geändert von Jasocul (13. Jul 2017 um 09:55 Uhr)
  Mit Zitat antworten Zitat
hoika

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

AW: Vorhandensein eines Records prüfen

  Alt 13. Jul 2017, 10:57
Hallo,
Select Count(*) ist indiskutabel (Testserver: 50 Sekunden. Live-Server knapp 3 Sekunden).

Hier kommt es auch an, wie viel der Server zählen muss (=Anzahl der Ergebnisse).

Aber wir reden ja nicht von MS-SQL, sondern von einem richtigen DB-Server (Firebird)
Heiko
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

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

AW: Vorhandensein eines Records prüfen

  Alt 13. Jul 2017, 11:09
wie wäre es mit
select distinct 1 from mytable where myid is not null ganz klar schneller als
Code:
select Count(*)
wobei die Zeiten von Jasocul ja wirklich jehnseits von gut und böse sind.

Gruß
K-H
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
hoika

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

AW: Vorhandensein eines Records prüfen

  Alt 13. Jul 2017, 11:57
Hallo,
select distinct 1 from mytable where myid is not null ganz klar schneller als
Das liefert doch aber zurück, ob es überhaupt einen Eintrag in der Tabelle gibt.

Ich denke, dass First schneller als Distinct ist.
Das Distinct muss ja erst die Ergebnismenge ermitteln, um dann darauf Distinct auszuführen.

Bei der SELECT RDB$RELATIONS.RDB$RELATION_NAME Abfrage stellt sich für mich die Frage,
was passiert, wenn der letzte Eintrag meiner Ergebnismenge (where myid=X) gelöscht wird.
Ist die Statistik dann trotzdem korrekt, zeigt also keine Einträge an,
oder wird der gelöscht Eintrag immer nicht berücksichtigt?.

Any record that has had its primary key modified will appear twice if the old version has not been garbage collected and deleted records will continue in the count until they are garbage collected.
Das sieht hier eben so aus, als ob auch die Garbage-Einträge mit gezählt werden.
Heiko

Geändert von hoika (13. Jul 2017 um 11:59 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

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

AW: Vorhandensein eines Records prüfen

  Alt 13. Jul 2017, 16:21
Hallo,
select distinct 1 from mytable where myid is not null ganz klar schneller als
Das liefert doch aber zurück, ob es überhaupt einen Eintrag in der Tabelle gibt.
das wolltest du doch? oder hab ich da was mißverstanden?

Wenn Du aus einem (Delphi) Programm heraus diese Frage stellst, reicht es ja auch nur den ersten Datensatz abzuholen, und den evtl vorhandenen Rest vergißt Du einfach??

Gruß
K-H
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 14:04 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