Seite 2 von 3

Re: PHP 7.xx: fbclient.dll bzw. gds32.dll wird nicht installiert.

Verfasst: Mo 3. Jun 2019, 12:14
von bfuerchau
Andere DB's mögen die Anzahl Sätze daher kennen, dass sie die Daten grundsätzlich erst intern in eine Arbeitstabelle kopiert bevor sie zurückgegeben wird.
Dies funktioniert auch i.d.R. nur bei statischen Cursor'n.
Bei dynamischen Cursorn kann sich die Datenbasis während der Abfrage noch ändern.
Manchmal ist der Wert aber auch nur eine Abschätzung der zu erwartenden Daten, je nach Implementation.

Da die Firebird die Daten aber bereits beim Lesen zur Verfügung stellt, ist die Anzahl der Datensätze vorher nicht zu ermitteln.
So etwas zu realisieren würde eine drastische Performanceeinbuße mit sich bringen, da dann tatsächlich erst alles ermittelt werden müsste, bevor die erste Datenzeile zurückgegeben werden kann.
Auf Grund der möglichen sehr komplexen Abfragetechnik, [rekursive] CTE's, union/left/right/inner Joins, derived tables usw., ist dies sehr aufwändig.
Hinzu käme ebenso der z.T. enorme Platzbedarf für die temporäre Kopie der Daten.

Jede Abfrage, die Indizes verwenden kann und somit keine temporären Daten benötigt, ist da immer vorzuziehen.

Wer unbedingt die Anzahl Sätze vorher benötigt, kann auch einen
Select count(*) from
(<Ursprungsselect>) x
durchführen. Er darf sich dann aber nicht über Performancenachteile wundern. Auch Abfragen von unter 100ms verdoppeln sich dadurch in der Queryzeit.

Zu berücksichtigen ist auch noch, dass durch das Versioning, dynamische Cursor ausgeschlossen sind, da Transaktionen nun mal das gleichzeitige Lesen von veränderten Daten durch aktive andere Transaktionen verhindert.
Beim Einsatz von Autocommit, kann also auch eine Count(*) gefolgt von der nächsten Abfrage durchaus ein anderes Ergebnis bringen, es sei denn ich arbeite sowieso alleine mit der Datenbank und verwende keine parallelen Verbindungen.

Re: PHP 7.xx: fbclient.dll bzw. gds32.dll wird nicht installiert.

Verfasst: Mo 3. Jun 2019, 12:57
von martin.koeditz
@bfuerchau
Danke für die ausführliche Antwort. Damit sind auch einige Interna des DBMS erklärt.
Select count(*) from
(<Ursprungsselect>) x
Vielleicht macht es Sinn dies als Funktion in den PHP-Treiber zu implementieren, mit Hinweis auf all die Nachteile. Dies liegt dann in der Verantwortung des Benutzers.

Gruß
Martin

Re: PHP 7.xx: fbclient.dll bzw. gds32.dll wird nicht installiert.

Verfasst: Mi 5. Jun 2019, 10:20
von bfuerchau
Ich bezweifle, dass es einen performanten Weg gibt, die Anzahl der möglichen Sätze performant zu ermitteln. Für Fortschrittsanzeigen wäre das sicherlich hilfreich.

Da Firebird grundsätzlich mit Satzversionen arbeitet ist eine schnelle Ermittlung einfach nicht möglich.
Durch das Überlesen von Transaktionsdaten, die für die aktuelle Abfrage nicht relevant sind, ist eben das Scannen der Daten grundsätzlich erforderlich.
Datenbanken ohne Satzversionen benötigen dies nicht.
Der SQL-Server arbeitet nur in Ausnahmefällen mit Satzversionen, nämlich genau dann, wenn ein After-Trigger die geschriebenen Daten nochmals ändert.
Ansonsten gilt z.B. folgendes:
https://community.idera.com/database-to ... ncy-issues

"Read Committed

This is the default Isolation Level for SQL Server and its sole purpose is to prevent “dirty reads”. It does this by placing a SHARED LOCK on the table when it is read. This lock will allow other SELECT transactions to read the same data but will not allow INSERT, UPDATE or DELETE transactions. These subsequent transactions will be BLOCKED until the first SELECT transaction completes."
D.h., dass eine Abfrage von Daten einer Tabelle diese gegen Veränderungen schützt.
Um also nicht zu lange Sperren aufrecht zu halten, ist die DB ja gezwungen, die Daten für den Abruf separat zur Verfügung zu stellen, da ja nicht klar ist, wie lange der Client denn benötig, die Daten zu lesen.

Durch die Satzversionen von Firebird ist dies überhaupt nicht erforderlich, so dass eben alle SQL's in parallelen Abfragen noch möglich sind.

Bei meinen BI-Auswertungen kann es schon mal zu Abfragedauern von mehreren Minuten kommen, da ich schon mit mehr als 30 Joins Abfragen dynamisch erstelle.
Um also die Anzahl der Datensätze zu ermitteln, müsste ich vorher eine Tabelle erstellen (z.B. Global Temporary), mehrere Minuten die Daten per "insert into ... select ... from" kopieren, dann per Count die Anzahl ermitteln und anschließend abrufen.
Nun ist es leider so, dass während des Inserts die Daten auch dem Client bereits verfügbar gemacht werden könnten.

Wenn z.B. bei einem Order By kein Index vorhanden ist, müssen die Daten in einen temporären Bereich gestellt und sortiert werden.
Inzwischen spare ich mir sogar den Order By, da die Ausgabeelemente ja sowieso ihre eigenen Sortierungen durchführen.

Da sind die vielen bereitgestellten Funktionen von Firebird, z.B. die Partition-Funktionen, doch erheblich wichtiger.

Einer meiner Kunden stellt seine Anwendung von SQL-Server auf Firebird um, und muss dabei feststellen, dass die Firebird erheblich performanter als der SQL-Server ist. Dies liegt u.a. auch gerade in der sofortigen Bereitstellung von Ergebnisdaten.

PS:
Ggf. könnte ja auch folgende Eränzung helfen:

select * from (
Select ..., ROW_NUMBER() OVER(ORDER BY <AnyField>) AS RowNbr
from ...
) x
order by RowNbr desc

Dann enthält die Spalte RowNbr die Anzahl der noch zu lesenden Sätze.
Allerdings könnte dies die Abfragedauer auch verlängern, da auf jeden Fall eine komplette Sortierung vor Rückgabe erzwungen wird.

Re: PHP 7.xx: fbclient.dll bzw. gds32.dll wird nicht installiert.

Verfasst: Di 11. Jun 2019, 23:10
von vr2
Hi Bernd,
Hamburgo hat geschrieben:
So 2. Jun 2019, 15:35
ok, dann muss ich mir da wohl ne Krücke bauen, weil ich diese Info sehr
häufig nutze und da bin ich wohl nicht alleine.
ich nutze php und Firebird schon sehr lange, habe aber einen row_count als Seiteneffekt eines clientseitigen selects noch nie vermisst. Wofür brauchst Du das?

Innerhalb von SPL gibt es Firebirds Kontextvariable row_count, die Dir beim select zumindest sagt, ob es überhaupt eine Ergebnismenge gibt. Das ist manchmal ganz praktisch.

Grüße, Volker

Re: PHP 7.xx: fbclient.dll bzw. gds32.dll wird nicht installiert.

Verfasst: Mi 12. Jun 2019, 10:34
von bfuerchau
Dann lese mal die Doku dazu:
https://firebirdsql.org/refdocs/langref ... count.html

In a FOR SELECT loop, ROW_COUNT is incremented with every iteration (starting at 0 before the first).

After a FETCH from a cursor, ROW_COUNT is 1 if a data row was retrieved and 0 otherwise. Fetching more records from the same cursor does not increment ROW_COUNT beyond 1.

Was hilft dir das nun beim Select?
Da kann man auch selber zählen.
Bei Update/Insert/Delete macht es dann in einer Prozedur schon Sinn, wobei die Clientlibraries häufig auch "AfftectedRows"-Eigenschaften unterstützen.

Eine Satzanzahl ist halt für Fortschrittsanzeigen ganz nett, wenn man den User belustigen will. Das Problem hier:
Je nach Treiber gibt es unterschiedliche Meldungen:
- Nach dem Select und vor dem ersten Fetch (Syntax OK)
- Nach dem 1. Fetch
Wenn ich dann z.B. den .Net-Treiber nehme, dann dauert bei einer komplexen Abfrage die SQL-Analyse mit Zugriffspfaden ca. 6 Sekunden.
Der 1. Fetch, der dann die Ausführung startet pausiert den Treiber für ca. 20-30 Sekunden.
Das anschließende Ergebnis von ca. 40.000 Zeilen kommt dann in ca. 0,8 Sekunden..
Eine Fortschrittsanzeige kann daher überhaupt nicht verwendet werden, da die ja nach 30 Sekunden erst startet und schon gleich wieder voll ist.

Ich denke, dass nicht immer so viele Daten von der DB geladen werden, die Abfragen da aber durchaus auf Grund der Komplexität eben lönger dauern.
Hier wäre eher eine Indexanalyse und entsprechendes Anlegen der Indizes oder u.U. auch ein performateres Redesign des SQL's angebrachter und viel erfolgversprechender.

Re: PHP 7.xx: fbclient.dll bzw. gds32.dll wird nicht installiert.

Verfasst: Mi 12. Jun 2019, 17:40
von vr2
bfuerchau hat geschrieben:
Mi 12. Jun 2019, 10:34
Dann lese mal die Doku dazu:
https://firebirdsql.org/refdocs/langref ... count.html
[...]
Was hilft dir das nun beim Select?
Du hast doch bestimmt den letzten Satz von meinem Posting gelesen, der das wiedergibt, was in der Doku steht, oder? Und wo ich beschreibe, wofür das brauchbar sein kann, ohne zu zählen. ;-)

Grüße, Volker

Re: PHP 7.xx: fbclient.dll bzw. gds32.dll wird nicht installiert.

Verfasst: So 23. Jun 2019, 14:19
von Hamburgo
@all:
Entschuldigung, dass ich zuletzt nicht mehr an der Diskussion teilnehmen konnte, aber ich bin widererwartend etwas unter Stress geraten und andere Baustellen wurden schlagartig markant wichtiger.

@vr2:
Im Fokus meiner Produkt-Strategie liegt die Usability meiner Software, da hier meines Erachtens das größte Potential an Wertschöpfung liegt, sowohl innerbetrieblich, als auch nach Außen hin (Kunden) und dafür ist die Kenntnis eines row_count vom select für mich extrem wichtig, da ich anhand dieses Wertes in Abhängigkeit von der eingesetzten Hardware des Benutzers (PC / Laptop / Tablet / Smartphone, sowie deren Monitor-Auflösung) entscheide, wie ich die Daten optisch aufbereite.

Mir ist bekannt, dass viele es anders sehen, aber für mich ist "scrollen" die reinste Kapital-Vernichtung und ist, soweit irgendwie möglich, um jeden Preis zu vermeiden und durch andere Lösungen, wie z.B. Tabs, Accordion usw. zu ersetzen.

Um dafür eine gute Wahl treffen zu können, ist für mich unabdingbar zu wissen, ob aus einem select 2 / 4 / 10 / 25 / 50 usw. records rauskommen.

Auch entscheide ich über diesen Wert, ob überhaupt und wenn ja, welche Sortier- und/order Selektions-Werkzeuge ich anbiete.

Da ich meine Produkte für die Zielgruppe KMU designe, stehe selten bzw. eigentlich nie vor der Herausforderung 20.000, 40.000 oder mehr Zeilen zeitgleich verarbeiten zu müssen.

@bfuerchau:
Ich danke für die ausführliche Beschreibung der Fakten, die wohl gegen die Bereitstellung einer row_count-Funktion beim select durch FireBird sprechen, muß aber auch einräumen fachlich kaum folgen zu können.

Was ich Deinen Ausführungen zu entnehmen meine ist, dass Deine Draufsicht auf die Frage-Stellung von dem Bedarf dominiert wird, 40.000 Zeilen aus vielleicht 1 oder mehrere Millionen zu selektieren, während weitere hunderte oder tausende andere Anwender parallel updates, inserts und deletes absetzen und da greifen Deine Verarbeitungs-Zeit-Argumente sicherlich.

Es gibt jedoch auch eine große Gemeinde von Entwickerlen, deren täglich Brot es ist, ein select-Ergebnis von 1 - 50 oder 100 Zeilen in einer Umgebung von 1 bis 100 weiteren Anwendern zu verarbeiten und da stehen andere Bedürfnisse im Fokus, wie z.B. eine row_count-Funktion.

Die Frage, die sich hier doch stellt ist, wo will FireBird hin ?

Dem Beitrag "Firebird + php 7: Bug im connect" ist doch aus dem Dialog Volker und Martin klar zu entnehmen, dass FireBird aus dem PHP-Kern erstmal rausgeflogen ist und der Grund scheint klar, die FireBird-Fan-Gemeinde ist zu klein.

Wenn solche Ereignisse für die FireBird-Macher nicht von Bedeutung ist, ok, wenn doch, dann sollte man vielleicht Funktionen zur Verfügung stellen, welche z.B. MySqli so populär machen.

Dann würde ich z.B. anregen über den Vorschlag von Martin nochmals nachzudenken:
"Vielleicht macht es Sinn dies als Funktion in den PHP-Treiber zu implementieren, mit Hinweis auf all die Nachteile. Dies liegt dann in der Verantwortung des Benutzers."

Danke und viele Grüße
Bernd

Re: PHP 7.xx: fbclient.dll bzw. gds32.dll wird nicht installiert.

Verfasst: Mo 24. Jun 2019, 05:58
von vr2
Hi Bernd,
Hamburgo hat geschrieben:
So 23. Jun 2019, 14:19
Mir ist bekannt, dass viele es anders sehen, aber für mich ist "scrollen" die reinste Kapital-Vernichtung und ist, soweit irgendwie möglich, um jeden Preis zu vermeiden und durch andere Lösungen, wie z.B. Tabs, Accordion usw. zu ersetzen.

Um dafür eine gute Wahl treffen zu können, ist für mich unabdingbar zu wissen, ob aus einem select 2 / 4 / 10 / 25 / 50 usw. records rauskommen.
Dann erweitere Dein select zb so:

Code: Alles auswählen

select t.*, count(*) over () gesamt
from tbl t
rows 10
Damit bekommst Du die Gesamtanzahl der Ergebnismenge, selbst wenn Du zb für Paging nur die ersten 10 Zeilen brauchst, die hier auch nur abgeholt werden. Das Konstruklt dafür entstammt Firebirds window functions https://firebirdsql.org/file/documentat ... funcs.html, die Doku dazu im Firebird Server/doc-Verzeichnis ist besser. Schau Dir window functions an, damit lassen sich viele Fragestellungen elegant und performant lösen.
Hamburgo hat geschrieben:
So 23. Jun 2019, 14:19
Dem Beitrag "Firebird + php 7: Bug im connect" ist doch aus dem Dialog Volker und Martin klar zu entnehmen, dass FireBird aus dem PHP-Kern erstmal rausgeflogen ist und der Grund scheint klar, die FireBird-Fan-Gemeinde ist zu klein.

Wenn solche Ereignisse für die FireBird-Macher nicht von Bedeutung ist, ok, wenn doch, dann sollte man vielleicht Funktionen zur Verfügung stellen, welche z.B. MySqli so populär machen.
Die Firebird-Gemeinde ist nicht zu klein, um einen php-Treiber gestemmt zu kriegen. Bei dem Treiber war das Problem, dass derjenige, der zugesagt hatte, als Maintainer den Treiber zu betreuen, das über Jahre nicht getan hat, aber auch nicht Bescheid gesagt hat, dass er sich nicht (mehr) kümmern kann oder will. Die Firebird-Stiftung (es steckt ja kein großer Konzern dahinter, sondern die Community) hat leider erst davon Wind bekommen, als ich Alarm geschlagen habe. Da war es schon zu spät, die php-Leute hatten von den jahrelangen leeren Versprechungen die Schnauze voll. Ich fand, sie haben etwas überreagiert, weil sie am Schluss von ganz offizieller Seite schon wussten, dass es weitergehen würde, aber irgendwann reicht es wohl.

MySQL ist immer noch kein Vergleich zu Firebird, schreib mal SPs/Trigger in MySQL oder mach Replikation oder backup einer DB, ohne sie außer Betrieb zu nehmen. MySQL ist an vielen Stellen nicht standardkonform und wurde erst nach und nach zu einer halbwegs brauchbaren relationalen DB. Eine Fibu oder Wawi mit nennenswert Businesslogik IN der DB würde ich damit nicht umsetzen wollen, einen DWH-Generator oder Reporting System erst recht nicht. MySQL hat einige Convenience-Features entlang der Denke von außerhalb der relationalen DB-Welt, wie auch MSSQL, die auch erst spät auf den Zug relationale Datenbanken aufgesprungen sind. Window Functions hat MySQL erst in Version 8, also bei einem Hoster noch gar nicht. Und ob die wirklich professionell nutzbar umgesetzt sind, ist bei MySQL bei allem, was über Standardfeatures hinausgeht, immer die Frage. Oft gab es blödsinnige Einschränkungen oder Sonnenscheinbedingungen wurden vorausgesetzt und man fragte sich ab und zu, ob man im Datenbank-Kindergarten ist.

Grüße, Volker

Re: PHP 7.xx: fbclient.dll bzw. gds32.dll wird nicht installiert.

Verfasst: Mo 24. Jun 2019, 14:33
von Hamburgo
Hallo Volker,

es ist sehr beruhigend zu wissen, dass die FireBird-Gemeinde groß genug ist, sodass wohl nicht die Gefahr besteht, das die DB irgendwann eingestampft wird und mit Martin hat sie wohl jetzt einen recht engagierten Maintainer für PHP.

Da mein DB-Know-How nicht einmal die Standardfeatures voll ausschöpft und das wird sich auf Grund meines Alters auch nicht mehr ändern, ist es für meine Produkte eigentlich egal, welche DB dahinter steht und das ist auch gut so, weil es durchaus denkbar ist, dass ein Kunde mir mal die DB vorschreibt.

Ich bin zu FireBird gekommen, weil mein damaliger DB-Spezialist die DB ausgesucht hatte, da sie wohl zu dem Zeitpunkt (1999) die einzige DB war, die ohne Port nutzbar war und das war für uns wichtig, weil unsere Kunden keine Admin-Rechte hatten, um Ports in der FireWall freizugeben.

Für meine heutigen Produkte ist der Hauptgrund an FireBird festzuhalten, einer derer, die Du auch aufgeführt hast, nämlich die Erstellung von BackUps, ohne sie ausser Betrieb nehmen zu müssen und dass man problemlos die Dateien von Rechner zu Rechner portieren und dort sofort nutzen kann. Einfach verbinden und los gehts. ;))

Herzlichen Dank für Deinen Code-Vorschlag.

Aber wenn ich das richtig verstehe, dann ist diese Lösung sehr firebird-speziell und ich müsste alle meine Selects anpassen (in einem Großteil von 1.230 Scripten).

Erstens wäre mir das zuviel Aufwand und zweitens stiege die Abhängigkeit zu FireBird auf ein Niveau, dass ich nicht möchte.

Daher hege ich noch immer die Hoffnung, dass Martin einen FireBird-Entwickler findet, den einen Geistes-Blitz ereilt und uns unter vertretbarem Aufwand eine performate row_count-Funktion schenkt, ohne das Nutzern von Groß-Datenbanken dadurch Nachteile entstehen.

Sollte dem leider nicht so sein, dann baue ich mir halt eine zentrale Krücke unter Verwendung von "SELECT COUNT(*)".

Das schluckt dann zwar etwas Performance, weil ich jedesmal den "FROM tbl WHERE"-Teil rausschneiden und 2 Selects absetzen muss, aber ich gewinne diese ja wohl später wieder mehr als zurück, wenn ich auf PHP 7.x und FireBird 3.x umsteige.

Danke und viele Grüße
Bernd

Re: PHP 7.xx: fbclient.dll bzw. gds32.dll wird nicht installiert.

Verfasst: Mo 24. Jun 2019, 19:49
von bfuerchau
Also ein "Select count(*) from Table" ohne den Where-Teil halte ich da doch für sinnlos.

Mach einfach einen

"Select count(*) from (" + UrsprungsSelect + ") hugo"

daraus. Wenn deine SQL's normalerweise performen könnte eine solche Abfrage auch unter 1 Sekunde liegen, da ja keine Daten transportiert werden müssen.
Ich glaube auch nicht, dass du dies für alle SQL's brauchst.

Und diese "Window"-Funktionen sind inzwischen in vielen DB's standard und werden immer wieder gerne verwendet und erweitert. Die FB hat sie nun nur halt auch.

Und was verstehst du unter zu alt?
Ich bin nun 61 und mache 43 Jahre IT, damals quasi noch zu fuß.
Und für zu alt, immer wieder was neues zu lernen, fühle ich mich nicht-