Flask Sqlalchemy query im Cache speichern und weitere Methoden auf die gecachte query anwenden?

Django, Flask, Bottle, WSGI, CGI…
Antworten
Zoja
User
Beiträge: 145
Registriert: Freitag 28. Februar 2014, 14:04

Hallo zusammen.

Ich bin dabei zu überlegen wie ich meine APP optimieren kann, hierbei ist mir aufgefallen, dass es sinnvoll wäre bei meiner Ergebnisseite meine initiale query irgendwie zu cachen.

Es geht um folgendes:

User suchen nach einem Zimmer in einer Stadt und kommen auf eine Ergebnisseite. Hier sind Zimmer zu sehen aus der Stadt:

Code: Alles auswählen

query = db_session.query(Zimmer)


Nun gibt es auf dieser Ergebnisseite mehrere Möglichkeiten Ergebnisse zu sortieren und filtern, hier ein Beispiel für das Filtern nach einem bestimmten Attribut:

Code: Alles auswählen

if form.validate_on_submit():

        query = db_session.query(Zimmer)

        filter_list = ["haustiere_erlaubt","bettwaesche_wird_gestellt","grill_vorhanden","safe_vorhanden","kuehlschrank_vorhanden","rauchen_erlaubt","parkplatz_vorhanden",
                    "kochmoeglichkeit_vorhanden","restaurant_im_haus_vorhanden","handtuecher_werden_gestellt","tv_vorhanden","waschmoeglichkeit_vorhanden","wlan_vorhanden"]

        for filter_name in filter_list:
            if getattr(form, filter_name).data:
                query = query.filter(getattr(Zimmer, filter_name).is_(True))
Das Problem ist hier, dass ich wieder die initiale Query mache und dann gucke, ob eine Checkbox true ist und wenn ja, dann füge ich zur Query einen Filter hinzu.

Genauso mache ich das fürs Sortieren. Wenn sortiert werden soll, kommt ebenfalls ein

Code: Alles auswählen

order_by()
hinzu.

Ich habe schon etwas gesucht und wahnsinnig viel gefunden, sogar eigene Module, die ich einbauen muss, um aus meiner APP eine chached APP zu machen.

Die Frage ist:
Kann mir jemand etwas empfehlen?
Ist es sinnvoll es zu machen?
Ist es sehr schlimm, dass ich es jetzt nicht mache?

Hier die Seite mit Beispieleingabe Berlin:
http://www.monteurzimmer-1a.de/suche/Berlin/1
Zuletzt geändert von Anonymous am Montag 30. Januar 2017, 18:44, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
BlackJack

@Zoja: Optimieren bedeutet ja Du hast gemessen wie schnell die Abfragen jetzt sind, um vergleichen zu können ob und wie viel *irgendeine* Massnahme bringt. Und dabei natürlich auch den Anteil der Abfrage am bisherigen Zeitverbrauch von Absenden bis vollständiger Darstellung des Ergebnisses berechnet. Wie hoch ist der denn?

Solange es kein nachweisliches, mindestens messbares Problem damit gibt, würde ich auch nicht anfangen irgend etwas zu optimieren. Im ungünstigen Fall bringt es nichts ausser zusätzlichem Speicherverbrauch für den Cache und dadurch dann am Ende vielleicht sogar Geschwindigkeitseinbussen.

Dann wäre da noch die Frage ob Du mittlerweile auf eine spezialisierte Geo-Datenbank für Umkreissuche setzt, oder immer noch die Zimmer alle abfragst und filterst. Das würde ich angehen bevor ich über Caching nachdenken würde.

Wenn Caching dann auch erst einmal bei der Datenbank selbst schauen was man da machen kann, beziehungsweise was die so macht.

Warum bekommt man unter der angebenen URL mit Berlin ein Wohnheim in 49809 Lingen(ems) in den Treffern? :-)
Benutzeravatar
pyHoax
User
Beiträge: 84
Registriert: Donnerstag 15. Dezember 2016, 19:17

Ich sehe nicht wie sich die Abfrage auf eine Datenbanktabelle sinnvoll cachen läßt..
Du muss doch rechnen das die Tabelle nicht mehr aktuell ist.
Jeder Versuch deinen Cache mit der Datenbank synchron zuhalten kostet Betriebsystemcalls für Netzwerkkommunikation ... ms ..

Sehe ich richtig das du die Tabelle aller Zimmer abfragst und diese dann Clientseitig (Datenbankclient. deine FlaskApp) filterst ?
Lass die Datenbank die Zimmerfiltern, dafür ist sie gemacht.
BlackJack

@pyHoax: Zumindest der gezeigte Code lässt die Datenbank filtern und sortieren.
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

pyHoax hat geschrieben:Ich sehe nicht wie sich die Abfrage auf eine Datenbanktabelle sinnvoll cachen läßt..
Du muss doch rechnen das die Tabelle nicht mehr aktuell ist.
Das sollte ein Problem sein weil?
Jeder Versuch deinen Cache mit der Datenbank synchron zuhalten kostet Betriebsystemcalls für Netzwerkkommunikation ... ms ..
Hast du überhaupt Ahnung wovon du redest?
Sehe ich richtig das du die Tabelle aller Zimmer abfragst und diese dann Clientseitig (Datenbankklient. deine FlaskApp) filterst ?
Nein, was auch wohl auch die vorige Frage beantwortet.
Lass die Datenbank die Zimmerfiltern, dafür ist sie gemacht.
Grad eben noch war die Performance wichtig und jetzt möchtest du dafür einen Roundtrip von Frontend durchs Backend zur Datenbank und zurück machen?
Zoja
User
Beiträge: 145
Registriert: Freitag 28. Februar 2014, 14:04

Vielen Dank Leute!

@BlackJack Ich lade nicht mehr alle Zimmer. Ich lade alle Zimmer in einem Umkreis um den gesuchten Ort. Sind ca. 60km um die Input Stadt, das mache ich auch bereits mit der DB:

Code: Alles auswählen

		query = db_session.query(Zimmer).filter(func.acos(func.sin(loc_latitude) * func.sin(Zimmer.zimmer_lat) + func.cos(loc_latitude) * func.cos(Zimmer.zimmer_lat) * func.cos(Zimmer.zimmer_lng - (loc_longitude))) * 6371 <= 2000)
Die Ladezeiten sind sehr schnell. Beim Optimieren dachte ich es wäre klüger die DB Anfragen zu reduzieren, aber ich habe nicht dran gedacht, dass dann der Cache natürlich zu sehr belastet werden könnte.
BlackJack

@Zoja: Damit gehst Du aber immer noch alle Zimmer durch. Wenn es schnell genug ist okay, aber das wäre dann mein erster Ansatzpunkt wenn es anfängt zu langsam zu werden sich GIS-Erweiterungen für das verwendete DBMS zu suchen oder ein entsprechendes DBMS für das es so etwas gibt.
Zoja
User
Beiträge: 145
Registriert: Freitag 28. Februar 2014, 14:04

BlackJack hat geschrieben:@Zoja: Damit gehst Du aber immer noch alle Zimmer durch. Wenn es schnell genug ist okay, aber das wäre dann mein erster Ansatzpunkt wenn es anfängt zu langsam zu werden sich GIS-Erweiterungen für das verwendete DBMS zu suchen oder ein entsprechendes DBMS für das es so etwas gibt.
Alles klar! Danke dir. Werde ich im Hinterkopf behalten.
Benutzeravatar
pyHoax
User
Beiträge: 84
Registriert: Donnerstag 15. Dezember 2016, 19:17

Das sollte ein Problem sein weil?

Jeder Versuch deinen Cache mit der Datenbank synchron zuhalten kostet Betriebsystemcalls für Netzwerkkommunikation ... ms ..


Hast du überhaupt Ahnung wovon du redest?
Ja .. hab ich. Punkt.
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

pyHoax hat geschrieben:
Das sollte ein Problem sein weil?

Jeder Versuch deinen Cache mit der Datenbank synchron zuhalten kostet Betriebsystemcalls für Netzwerkkommunikation ... ms ..


Hast du überhaupt Ahnung wovon du redest?
Ja .. hab ich. Punkt.
Den Eindruck vermittelst du aber nicht. Der Cache ist doch gerade dafür da, häufig genutzte Abfragen im Speicher zu realisieren. Eine Synchronisation ist dabei nur für Daten nötig, die als veraltet markiert wurden. Im Endeffekt soll es I/O einsparen. Normalerweise nutzt das DBMS aber einen eigenen Cache, sodass man dies nicht selbst implementieren muss.
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

snafu hat geschrieben:Normalerweise nutzt das DBMS aber einen eigenen Cache, sodass man dies nicht selbst implementieren muss.
Naja, eine Datenbank hat zwar normalerweise Caches für ein paar Sachen und hält Informationen im Arbeitsspeicher aber dass heißt noch lange nicht das Ergebnisse von Queries gecached werden, erst recht nicht automatisch. Postgres z.b. tut dies nicht.
Antworten