2017-10-17 417 views
0

所以我面臨一個困難的情況,我有一個遺留應用程序,寫入和設計不好,有一個表,t_booking。這個應用程序,具有日曆視圖,其中,爲每一位大廳,並每天都在一個月,顯示出其保留狀態,與此查詢:使用UNION ALL從視圖優化查詢

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; 

(起初也有一個ORDER BY r.estado DESC我拿出)

這個查詢,適當的(我認爲)索引後,每個需要0.004秒,並在合理的時間內呈現整個日曆視圖。有idhotel,idhall和日期索引。

現在,我有一個新模塊,寫得很好;-),它在另一個表中進行了保留,但是我必須在同一個日曆視圖中顯示這兩種保留類型。我的第一個方法是創建一個視圖,加入兩個表的內容,並從這個視圖中選擇日曆視圖的數據,而不是t_booking

的視圖被定義如下:

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 
; 

(表new_hall_reservation具有相同索引)

我tryed UNION ALL代替UNION因爲我讀這是更有效的。

那麼,前者的查詢,爲t_booking_hall_reservation改變t_booking,需要1.5秒,乘以每個大廳和每一天,這使得日曆視圖不可能完成。

該應用程序是spaguetti代碼,因此,循環兩次,一次超過t_booking,然後超過new_hall_reservation,並且結果在某種程度上很難。

是否可以調整視圖以使此查詢足夠快?另一種方法?

感謝

PS:欠我修改原始查詢,我需要修改遺留應用程序,這是在少之更少,風險修改

+0

'JOIN'應該是第二個'SELECT'的一部分嗎?還是'UNION'結果集的一部分? –

+0

@RickJames,JOIN是第二個SELECT的一部分 –

+0

請提供'SHOW CREATE TABLE',以便我們知道索引是什麼。 –

回答

0

這是太長評論。

視圖(幾乎)永遠不會幫助性能。是的,他們使查詢更簡單。是的,它們包含了重要的邏輯。但是,不,他們沒有幫助表現。

一個關鍵問題是視圖的執行 - 它通常不考慮整個表中的過濾器(雖然最新版本的MySQL在這方面更好)。

一個建議 - 這可能是一個相當的工作 - 是實現視圖作爲一個表。當基礎表發生變化時,您需要使用觸發器更改t_booking_hall_reservation。然後,您可以在表格上創建索引以實現您的績效目標。'

+0

有趣的想法 –

0

t_booking,除非它是一個VIEW,需要

INDEX(idhotel, idhall, date) 

VIEWs是語法糖;他們不提高表現;有時它們比等效的SELECT慢。