Ich habe einen Vorschlag mit entsprechenden Hinweisen ins Git-Forum eingebracht.
https://github.com/FirebirdSQL/NETProvider/issues/1110
Aber selbst nach 5 Tagen hat noch niemand darauf reagiert.
Die Quellen liegen ja vor und ich habe mir das Thema mal angesehen.
Allerdings sind da so viele Abhängigkeiten gegeben, dass eine einfache Umsetzung nicht möglich scheint.
Es steht und fällt mit dem sog. FetchSize (max. 32768). Dieser beschreibt die max. Anzahl Zeilen, die mit einem Call vom Server abgerufen werden können.
Diese werden erst in eine Queue geschrieben und dann bei jedem Read() aus der Queue gelesen. Hierbei wird dann je Zeile eine DbValue[] Array erstellt, dass die Werte enthält.
Bei 1.Mio. Zeilen also 1 Mio.*Anz.Spalten DbValue-Objekte.
Beim Lesen wird jedoch nur 1 einziges DbValue[]-Array benötigt, da GetValue den eingebetten Spaltenwert als Single-Objekt zurückgibt.
Diese Objekte sind kein Problem, da man mit diesen ja i.d.R. weiterarbeitet, wenn sie z.B. in ein DataTable einfließen.
Bei jedem Read() wird das DbValue[] Array überschrieben und diese Objekte in den Garbage geschickt. Ca. nach 2 Mio. Zeilen schlägt der GC dann erbarmungslos zu, gibt Objekte frei und reorganisiert den Speicher und bremst das Laden dann aus.
Aber wer braucht denn wirklich mehr als 2 Mio. Zeilen für eine Abfrage?
Wir leider, für unsere Dashboards.
Ich habe mich daran selbst versucht, bin jedoch kläglich gescheitert.
Ich konnte zwar das DbValue[]-Array für die Queue als Object[]-Array für die Werte ersetzen, allerdings nicht die Queue. Dadurch ergab sich ein leichter Vorteil von 10-30% je nach Anzahl Spalten.
Rufe ich die Daten ohne Queue mit einem Read() ab, geht der Geschwindigkeitsvorteil wieder vollkommen verloren. Zusätzlich tritt ein Transaktionsproblem auf, da u.U. nicht alle Daten aus dem internen Puffer ausgelesen werden, z.B. beim internen GetSchemaTable des FbDataReaders, der dieselben Funktionen verwendet.
Hinzu kommt, dass die Vorschläge wahrscheinlich gar nicht aufgenommen werden, da sie mit den Async-Methoden von Net-Core vollkommen hinfällig sind.
Auch kann ich nichts dazu sagen, wie sich das mit einer Client-App / Db-Server-Konstellation verhält, da ja dann noch das Netzwerk dazu kommt und da weitere Bremsen entstehen. Wir haben z.B. getrennte Server für Web (IIS) und Datenbank (FbServer) gefordert um keine Ressourcen-Konkurrenz (Speicher/CPU's) zwischen beiden zu bekommen.
Das Ganze ist also nur sinnvoll bei einer Single-Server-Lösung, also App und Db-Server auf der selben Kiste.
Anscheinend wird ab Net-Core alles Asynchron (Async/Await) über Task's geregelt.
Da sinkt der Durchsatz gegenüber .Net-Framework 4.8 im Schnitt sowieso um über 50% da das Erstellen von Threads (hier Task's) einen gigantischen Overhead mit sich bringt, dass die Leserate von ca. 320.000 Zeilen/Sekunde dann auf 120.000 Zeilen / Sekunde sinkt. Da ist der Gabagecollector dann glatt noch unterfordert.
Es ist also nicht alles Neue dann tatsächlich auch gut, wenn sich Antwortzeiten für Dashboards dann verdreifachen können. Keine rosigen Aussichten.
Da ist es dann auch kein Wunder, dass man mit Power BI in die Cloud muss, da man dieses o.a. Manko nur mit entsprechend mehr Ressourcen ausbügeln kann, was OnPremises, wie unsere Lösung, kaum zu leisten ist.
Ob da wohl eine bestimmte Absicht hinter steht
?
Was deinen PHP-Treiber angeht, so können wir uns das beide gerne mal zusammen ansehen. Ich glaube aber nicht, dass du den Net-Client intern anwendest.