Hallo,
diesmal hab ich eine spezielle, wohl eher exotische Frage:
Um den kürzesten Weg zwischen zwei Benutzern eines sozialen Netzwerks zu finden, verwenden wir einen von uns in PL/PgSQL geschriebenen Dijkstra. Nun ist es so, dass in extrem ungünstigen Situationen trotz Tunings (Einsatz eines HashMap-/Queuetyps bei der Berechnung, Verwendung einer geringeren Maximalsuchtiefe) der Funktionsaufruf mit manchmal mehreren Sekunden deutlich zu lange dauert.
Das sind immer solche Fälle, bei denen letztendlich keine Verbindung gefunden werden kann. Klar, es muss ja schließlich bis zur Maximalsuchtiefe alles abgesucht werden, um das wirklich sicher sagen zu können.
Da sich die Pfade in der Praxis nicht memcachen lassen und wir eine schnelle Antwortzeit noch mehr als die absolute Verlässlichkeit der Aussage brauchen, ist mir folgende Idee gekommen:
Wenn man der Funktion sozusagen eine Maximal Execution Time mitgibt, könnte diese nach Ablauf dieser Frist (möglicherweise frühzeitig) terminieren. In diesen Fällen würden wir das Ergebnis als "nichts gefunden" interpretieren.
Habt ihr eine elegantere Idee, als selbst einen Zeitstempel zu Beginn zu setzen und im eigentlichen Dijkstra regelmäßig die Ablaufzeit zu kontrollieren?
Gibt es vielleicht sogar eine Postgres-Möglichkeit zur Angabe einer individuellen Maximal Execution Time für ein Statement? Ich bin da in den entsprechenden Quellen nicht fündig geworden.
Danke für Eure Tips,
az_hf0
Du kannst es mal mit statement_timeout probieren:
Aber das killt Dir die TX, was Du wohl eher nicht willst. Innerhalb einer function kannst Du aber deren Ausführungszeit recht simpel abfragen:Code:test=*# select * from words where x = 'foobarbatz'; w | x ---+--- (0 rows) Time: 257.012 ms test=*# set statement_timeout=10; SET Time: 0.258 ms test=*# select * from words where x = 'foobarbatz'; ERROR: canceling statement due to statement timeout test=!#
da now() die Startzeit der aktuellen TX und timeofday() die wirkliche Zeit (als String) liefert. IIRC gibt es auch eine Funktion, die direkt einen timestamptz liefert, bin nur grad zu faul, danach zu suchen.Code:test=# select timeofday()::timestamptz - now(); ?column? ----------------- 00:00:00.000343 (1 row) Time: 0.371 ms test=*# select timeofday()::timestamptz - now(); ?column? ----------------- 00:00:00.956589 (1 row) Time: 0.432 ms test=*# select timeofday()::timestamptz - now(); ?column? ----------------- 00:00:01.760662
Andreas
--
https://www.xing.com/profile/Andreas_Kretschmer7ads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
Danke für den Tip.
Auf den ersten Blick hat jetzt statement_timeout bei mir nicht das gewünschte Ergebnis gebracht, aber das werde ich mir nochmal ansehen.
Der timeofday()-Trick ist auf jeden Fall nett, vermutlich werde ich diesen Weg einschlagen.
Viele Grüße,
az_hf0
Links: Tobias Bauer - IT- und Funkdienstleistungen - Bilderrahmen-kaufen.de - Der Onlineshop für Bilderrahmen & Fotorahmen - Funkforum
Lesezeichen