Hallo zusammen,
wir verwenden in unserem Programm u.a. solche Methoden hier:
DataTable dt = pgCon.GetSchema(“IndexColumns”);
Die Variable “pgCon” ist dabei vom Typ “Devart.Data.PostgreSql.PgSqlConnection”.
Diese Methode funktioniert bei unserem hausinternen PGSQL-Server tadellos und benötigt nur wenige Sekunden für beispielsweise ~7K Datensätze.
Bei einem PGSQL-Server, welcher auf einer Maschine bei IONOS gehostet wird, dauert der Zugriff jedoch ewig, so locker 2 Minuten. In der Zeit ist der ausführende Client so gut wie gar nicht ausgelastet, es wird nichts übertragen.
Weiß jemand, wo da die Ursache sein kann? Läßt sich sowas möglicherweise per Konfiguration ändern? Der Server hat Version 14.
Du könntest noch verraten, was GetSchema macht.
Es ist sicher kein Problem, von irgendwo 7K Datensätze zu lesen. Früher hätte ich gesagt, nimm lieber DSL statt ISDN, aber das trifft heute selten…
Wenn wie hier die Zahl der DS nicht groß ist, ist die nächste Frage, wie sie zusammen gestellt werden.
Bei einem Hoster wäre es möglich, dass er nicht viel Luft bietet für einen DB Server, je nach Tarif.
Da Deine Funktion offenbar irgendeine Programmierspache ist, kann man noch vermuten, dass sie komplex ist und eine Menge latenzbehaftteter Minioperationen ausführt. Die sind übers I-Netz oft relativ langsam. Im LAN fällt es dagegen kaum auf. Möglicher Ausweg: Mach das, was getSchema im Client macht auf dem Server und Du bist glücklich.
Hallo,
die GetSchema-Methode kommt vom Provider, in dem Fall von “DevArt” und dem dazugehörenden Objekt “PgSqlConnection”. Aber auch der native MSSQL-Client vom .NET (SqlConnection) kennt die GetSchema-Methode. Man übergibt in Klammern einen String, zum Beispiel “Tables”, “Columns”, ForeignKeys" etc. und bekommt eine Tabelle mit den gewünschten Infos. Wahrscheinlich geht dieser Befehl je nach Zielserver in eine der Systemtabellen des jeweiligen Servers.
In unserem Netz laufen sowohl MSSQL-Server als auch PGSQL-Server, bei denen dauert die jeweilige Abfrage eben nur wenige Sekunden. Lediglich der PGSQL auf dem Ionos-System braucht da so lange.
Könnte es Unterschiede bei PGSQL zwischen der Windows- und der Linuxvariante geben? In unserem Netz läuft nur Windows, Ionos hat Linux/Unix, keine Ahnung, welche Version genau. Vielleicht ist es auch ein Problem der dortigen .NET-Ausprägung. Obwohl der Rest der Software relativ gut läuft, da ist alles nur minimal zäher.
Also was GetSchema genau macht, kann ich dir nicht sagen. Aber es zuckt an 2 Stellen:
.Net:
ich vermute weiter, es ist ein “komplexer” Befehl eines Clients. Komplex bedeutet in diesem Fall, viele kleine Abfragen. Viele kleine Abfragen haben Latenzen. .Net hat dann noch die nette Eigenart - wenn ich mich richtig erinnere- dass es quasi zustandslos auf die DB zugreift, zumindest, wenn man es nicht anders verlangt. Zu den vielen kleinen Abfragen kommen also viele kleine Anmeldungen. Das Ganze hat m.E. den grandiosen Zweck, Serverressourcen zu schonen, coole Idee von Microsoft, vermutlich eher aus der Not geboren. Na egal, macht im Summe jedenfalls sehr viele Latenzen.
IONOS: Nichts gegen IONOS, das liegt im WAN / Internet, das macht viele kleine Latenzen nicht besser.
Ausweg: Frag die gewünschten Daten direkt vom Server ab, “in eigenen Worten”, wie es an der Schule immer hieß. Dann weißt Du genau was geschieht und wo es klemmt und es ist, so wie Du die Funktion beschrieben hast, auch nicht mega aufwändig.
Ansatzpunkt ist das “Information Schema” als standardisierte Schnittstelle genau dafür, wenn man auf den Standard verzichtet, kann man vieles auch mit pg spezifischen Abfragen erledigen, vlt etwas schneller…
Und noch mal .net: Ich habe mal vor vielen Jahren den Auftrag gehabt, einen Oracle Server zu beschleunigen. Man konnte mir nicht genau sagen, was da steht, welche Hardware, welche Version / Edition usw. Vor Ort habe ich festgestellt, dass es der fetteste DB Server war, den ich bis heute live gesehen habe. - also nicht wirklich gesehen, dran gearbeitet-
Ende vom Lied: es war eine .Net Komponente, die total praktische Sachen macht bzw. kann. Leider mit dem Nebeneffekt, dass sie initial mehrere 100 MB an Daten lädt. Ich musste nicht den Server tunen und konnte nach wenigen Stunden Suche wieder abhauen.
danke für deine ausführliche Nachricht. Ich fürchte auch, dass die Implementation von “GetSchema” ineffizient ist. Da muss ich tatsächlich mir was einfallen lassen. Es geht ja auch um keine Raketenwissenschaft, sondern um erprobte Dinge: Das Ermitteln der vorhandenen Tabellen, Spalten oder Fremdschlüssel ist ja nun nichts Neues. Das sollte auch mit einfachen SQL-Befehlen gehen, wenn man die betreffenden Systemtabellen kennt. Der Code bei uns wurde vermutlich neutral gehalten, weil das betreffende Programm flexible mit MSSQL, PG oder früher auch mit Oracle laufen sollte und “GetSchema” nun mal im .NET immer da ist. Ich schaue mir das an und gebe Feedback.
wenn du Debatte Komponenten nutzt, hast du schon Mal ein Ticket aufgemacht? Eventuell können die dir mehr sagen. Mit den .net Komponenten kenn ich mich nicht aus aber bei den Delphi Geschichten sind die super schnell und Kompetent.
ich bin leider immer noch an diesem lästigen Thema dran. Die “GetSchema”-Methode des .NET-Providers konnte ich teilweise ersetzen, aber ein wenig fehlt noch. Vielleicht kann mir jemand auf die Sprünge helfen.
So sieht es derzeit aus:
GetSchema(“Tables”) → “SELECT * FROM information_schema.tables WHERE table_schema = ‘public’”
GetSchema(“Columns”) → “SELECT * FROM information_schema.columns”
GetSchema(“ForeignKeyColumns”) → “SELECT * FROM information_schema.key_column_usage”
GetSchema(“Indexes”) → Indizes ermitteln?
GetSchema(“IndexColumns”) → indizierte Spalten ermitteln?
GetSchema(“ForeignKeys”) → Fremdschlüssel ermitteln?
Für die letzten drei Aufrufe fehlt mir noch ein Pendant. Die SELECT-Abfragen dauern übrigens nur einen Bruchteil gegenüber der generischen “GetSchema”-Methode, keine Ahnung, was der .NET Provider da treibt…
Join pg_index mit pg_attribute - das ist aber etwas umständlich, weil die Spalten die indiziert sind in einem Array stehen (pg_index.indkey). Das kann aber auch leer sein, weil es ja auch ein Ausdruck sein kann, nicht nur eine Spalte.
Wenn Du das nicht einzeln brauchst, reicht Dir vielleicht der Inhalt von pg_indexes.indexdef
Fremdschlüssel ermitteln?
select *
from from information_schema.table_constraints
where constraint_type = 'FOREIGN KEY`
Alternativ auch pg_constraint - aber auch hier sind die FK Spalten in einem Array “versteckt”.
danke dir. Ein klein wenig konnte ich noch optimieren, jetzt muss das Projekt leider wieder etwas ruhen.
Ich habe darüber hinaus festgestellt, dass der PG selbständig Indizes anlegt und zwar auf die referenzierten Spalten. Wir legen eigentlich diese Indizes per Programm an, was nun nicht mehr geht. Letztlich zählt ja auch nur, dass der Index vorhanden ist, auch wenn sie einen anderen Name bekommen.
Nur für primary und unique constraints werden automatisch Indizes angelegt. Da diese meistens auch das Ziel eines foreign keys sind, hat es zur folgen dass “referenzierte Spalten” indiziert sind. Aber nicht weil sie referenziert werden, sondern weil sie als unique definiert wurden.
Ah, das ist wahr… Offenbar gibt es noch einen Fehler in meiner Anwendung, denn während auf dem MSSQL-Server ein Index zum Beispiel so heißt “b4Ind_FK_T418_F100433” wird er auf dem PG so benannt: “fk_418_100433”. Das kann aber nur ein internes Problem sein.
Den Namen des Index gibt man doch beim Anlegen an (create index some_index on ....) - ich verstehe nicht, warum dann in den beiden Systemen unterschiedliche Namen entstehen sollten.
Ja, wie gesagt, das kann nur ein Fehler in unserem internen Code sein, dass muss ich noch analysieren, denn es macht ja überhaupt keinen Sinn. Da ist einfach irgendwo noch ein Bug…