2017-10-17 4 views
0

So habe ich ein schwieriges Szenario konfrontiert, ich habe eine Legacy-App, schlecht geschrieben und gestaltet, mit einer Tabelle, t_booking. Diese App hat eine Kalenderansicht, in der für jede Halle, und für jeden Tag im Monat, seinen Reservierungsstatus zeigt, mit dieser Abfrage:Abfrage von Sicht mit UNION ALL optimieren

SELECT mr1b.id, mr1b.idreserva, mr1b.idhotel, mr1b.idhall, mr1b.idtiporeserva, mr1b.date, mr1b.ampm, mr1b.observaciones, mr1b.observaciones_bookingarea, mr1b.tipo_de_navegacion, mr1b.portal, r.estado 
FROM t_booking mr1b 
LEFT JOIN a_reservations r ON mr1b.idreserva = r.id 
WHERE mr1b.idhotel = '$sIdHotel' AND mr1b.idhall = '$hall' AND mr1b.date = '$iAnyo-$iMes-$iDia' 
    AND IF (r.comidacena IS NULL OR r.comidacena = '', mr1b.ampm = 'AM', r.comidacena = 'AM' AND mr1b.ampm = 'AM') 
    AND (r.estado <> 'Cancelled' OR r.estado IS NULL OR r.estado = '') 
LIMIT 1; 

(anfangs war es auch ein ORDER BY r.estado DESC die ich herausgenommen)

Diese Abfrage, nach richtiger (ich denke) Indexierung, dauert 0,004 Sekunden, und die gesamte Kalenderansicht wird in einer angemessenen Zeit dargestellt. Es gibt Indizes über Idhotel, Idhall und Datum.

Jetzt habe ich ein neues Modul, gut geschrieben ;-), das Reservierungen in einer anderen Tabelle vornimmt, aber ich muss beide Arten von Reservierungen in derselben Kalenderansicht präsentieren. Mein erster Ansatz war das Erstellen einer Ansicht, Verbinden des Inhalts beider Tabellen und Auswählen von Daten für die Kalenderansicht in dieser Ansicht anstelle von t_booking.

ist die Ansicht wie folgt definiert:

CREATE OR REPLACE VIEW 
t_booking_hall_reservation 
AS 
SELECT id, 
     idreserva, 
     idhotel, 
     idhall, 
     idtiporeserva, 
     date, 
     ampm, 
     observaciones, 
     observaciones_bookingarea, 
     tipo_de_navegacion, portal 
    FROM t_booking 
UNION ALL 
SELECT HR.id, 
     HR.convention_id as idreserva, 
     H.id_hotel as idhotel, 
     HR.hall_id as idhall, 
     99 as idtiporeserva, 
     date, 
     session as ampm, 
     observations as observaciones, 
     'new module' as observaciones_bookingarea, 
     'events' as tipo_de_navegacion, 
     'new module' as portal 
FROM new_hall_reservation HR 
JOIN a_halls H on H.id = HR.hall_id 
; 

(Tabelle new_hall_reservation hat gleiches Indizes)

I tryed UNION ALL statt UNION, als ich las so viel effizienter ist.

Nun, die frühere Abfrage, t_booking für t_booking_hall_reservation ändern, nimmt 1,5 Sekunden für jede Halle zu multiplizieren und jedem Tag, die bis zum Ende der Kalenderansicht unmöglich macht.

Die App ist spaguetti Code, also, zweimal, einmal über t_booking Looping und dann über new_hall_reservation und die Kombination von Ergebnissen ist irgendwie schwierig.

Kann die Ansicht optimiert werden, um diese Abfrage schnell genug zu machen? Ein anderer Ansatz?

Dank

PS: Je weniger ich ursprüngliche Abfrage ändern, desto weniger werde ich das Erbe App ändern muß, die bei weniger ist, riskant

+0

Soll der 'JOIN' Teil des zweiten' SELECT' sein? Oder Teil des Ergebnisses der UNION? –

+0

@RickJames, JOIN ist Teil der zweiten SELECT –

+0

Bitte stellen Sie 'SHOW CREATE TABLE' bereit, damit wir wissen, was die Indizes sind. –

Antwort

0

Dies ist zu lang für einen Kommentar ändern .

Ein Blick ist (fast) nie zur Leistungssteigerung. Ja, sie machen Abfragen einfacher. Ja, sie enthalten wichtige Logik. Aber nein, sie helfen der Leistung nicht.

Ein Schlüsselproblem ist die Ausführung der Ansicht - es berücksichtigt im Allgemeinen nicht die Filter in den Gesamttabellen (obwohl die neuesten Versionen von MySQL hier besser sind).

Ein Vorschlag - der ein gutes Stück Arbeit sein könnte - besteht darin, die Ansicht als Tabelle zu materialisieren. Wenn sich die zugrunde liegenden Tabellen ändern, müssen Sie t_booking_hall_reservation mithilfe von Triggern ändern. Dann können Sie Indizes für die Tabelle erstellen, um Ihre Leistungsziele zu erreichen.'

+0

Interessante Idee –

0

t_booking, es sei denn, es ist ein VIEW ist, braucht

INDEX(idhotel, idhall, date) 

VIEWs sind syntaktischer Zucker; sie verbessern nicht die Leistung; manchmal sind sie langsamer als das Äquivalent SELECT.