Zimmerbelgung in einer View

=fire=

Erfahrenes Mitglied
Hallo,

ich würde gerne mein DB optimieren, da die Anfragen recht lage dauern. Das Problem ist das bei der Buchung Abgefragt wird ob an allen gewünschten Tagen mindestens ein Zimmer frei ist. Je länger der Zeitraum umso mehr Abfragen sind es, also pro Tag eine.

Jetzt überlege ich das in einer DB View pro Tag zu speichern, also z.B.:

2014-04-20: 100
2014-04-21: 95
...

Für die nächsten 24 Monate.


Die Buchungen werden als "von" "bis" Daten gespeichert.

Wie genau bewerkstellige ich das am besten?
 
Hmm,

ich denke nicht, dass durch das Anlegen der View sich irgendwas beschleunigen lässt. Mit einer View bekommt man keine Beschleunigung, denn im Hintergrund muss auch ein Select ausgeführt werden.

Viel mehr solltest du dir Gedanken machen, warum dein SQL so lange läuft. Schon mal mit SQL-Analyse-Tools (bei MySQL gibts da EXPLAIN) geschaut, was da so lange dauert?

Wie genau arbeitet deine Applikation an dieser Stelle?
 
Ich sobald man Ankunft und Abreise wählt wird per Ajax der Preis aus der DB berechnet und mit einer For schleife eine Abfrage für jeden Tag generiert und geprüft ob an einer der gewählten tage bereits die max anzahl der Plätze gleich ist.

Bei der zweiten Abfrage ist es dann deutlich schneller.

SQL:
SELECT COUNT(*) as count FROM reservation AS r WHERE type='3' AND reverse='0' AND (
				(r.in='2014-04-29') 
				OR (r.out='2014-04-29')
				OR (r.in <= '2014-04-29' AND '2014-04-29' <=r.out )
				)

id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE r ref parking_id type 4 const 5776 Using where
 
Zuletzt bearbeitet von einem Moderator:
Ok,

schon geprüft, ob sich mit entsprechenden Indizes irgendwas beschleunigen lässt? Da scheint sich auf IN, OUT, TYPE und reverse was machen zu lassen. Insbesondere bei den Datumsangaben könnte es was bringen.
 
Moin =fire=,

ergänzend zu saftmeister:

Wenn die beiden Datumsfelder IN und OUT nicht Nullable sind (was ich eigentlich annehme, da wohl niemand reservieren wird ohne An- und Abreisetag zu nennen), dann sollte hiermit das gleiche Resultset rausfallen:
SQL:
SELECT COUNT(*) AS COUNT FROM reservation AS r 
               WHERE TYPE='3' AND reverse='0' 
               AND r.IN <= '2014-04-29' AND r.OUT >='2014-04-29'


... allerdings mit ein paar ORs weniger, die das Ganze ausbremsen und ein paar Freiheiten mehr für den Optimizer.

Ich kann/wir können von hier aus nicht sehen, ob die Felder "reverse" und "Type" den Gesamtdatenwust signifikant filtern können, aber Indizes auf die Datumsfelder sollten sonst eine Performanceverbesserung bringen.


Wenn ein Index auf den beiden Datumsfeldern liegt, dann solltest du auch mit einer weiteren Bedingung "AND r.OUT > heute " die durchzuflöhenden Daten "performant" reduzieren können.


Grüße
Biber
 
Wenn ein Index auf den beiden Datumsfeldern liegt, dann solltest du auch mit einer weiteren Bedingung "AND r.OUT > heute " die durchzuflöhenden Daten "performant" reduzieren können.

Danke die Indexe und das kürzen der Abfrage haben einiges gebracht.

Ich habe noch folgendes ergänzt:

AND r.OUT>=NOW()

Ist die Reihenfolge hier ausschlaggebend, oder macht das der Optimizer selbst?

Gibt es irgendeine Regel wann man Indexe setzen sollte?
 
Moin =fire=,

zu deinen Fragen
Ist die Reihenfolge hier ausschlaggebend, oder macht das der Optimizer selbst?
Natürlich.

Gibt es irgendeine Regel wann man Indexe setzen sollte?
Es gibt Dutzende von Regeln - aber es sollte immer mit Augenmass und unter Berücksichtigung der spezifisch vorliegenden Tabellenstruktur abgewogen werden.

Einzige IMMER-Regel: Alle "technischen" Key-Spalten, also insbesondere für Foreignkey-Beziehungen genutzte Spalten(kombinatonen) sollten mit einem Index unterstützt werden.

Danach sollte geprüft werden, ob sich Indexe auf Felder lohnen, die "häufig" als Filterkriterien (Bsp.:"where Status="x") oder als Range/Sortierkriterien ("Zeitraum von... bis... absteigend") verwendet werden.

Lohnen heisst:
a) jeder Index bedeutet erhöhten Verwaltungsaufwand=Performanceverlust für die DB bei Insert/Delete/Update-Aktionen. und auch mehr Plattenplatzbedarf
b) bei häüfiger Änderungsfrequenz der Daten müssen auch mal Indexdateien reorganisiert/neu aufgebaut werden
c) nicht jeder Index muss sinnvoll sein: Wenn in deiner DB 90% der Datensätze oder auch nur 50% der Datensätze den Status="x" haben... warum sollte der Optimizer diesen Index nehmen? Es muss ohnehin mindestens jeder zweite Datensatz gelesen werden, also macht er gleich einen Tablescan. (Aber es gibt reichlich Datenbanken, bei denen solche Felder wie "Männlich"/"weiblich" oder "Aktiv"/"inaktiv" mit 50:50-Verteilung indiziert sind. Nur bringen tut es nix.)

-> Bei dir lohnt sich sicherlich eine Indizierung auf ein oder beide Datumsfelder, wie oben ja schon gezeigt.

Diese lustigen Felder "Status" und "Reverse" ... who cares? Bei grösste Selektivität hast du über die Datumsspalten - damit siebst du 800 von 1000 Datensätzen aus.
Die verbleibenden 200 Datensätze sollten dann nun wirklich in einem auch bei ALDI oder MediaMarkt handelsüblichen Arbeitsspeicher auf sonstige Randkriterien geprüft werden können.
Da also KEIN Index.

Grüße
Biber
 
Zuletzt bearbeitet:

Neue Beiträge

Zurück