使用UNION ALL从视图优化查询

使用UNION ALL从视图优化查询

问题描述:

所以我面临一个困难的情况,我有一个遗留应用程序,写入和设计不好,有一个表,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',以便我们知道索引是什么。 –

这是太长评论。

视图(几乎)永远不会帮助性能。是的,他们使查询更简单。是的,它们包含了重要的逻辑。但是,不,他们没有帮助表现。

一个关键问题是视图的执行 - 它通常不考虑整个表中的过滤器(虽然最新版本的MySQL在这方面更好)。

一个建议 - 这可能是一个相当的工作 - 是实现视图作为一个表。当基础表发生变化时,您需要使用触发器更改t_booking_hall_reservation。然后,您可以在表格上创建索引以实现您的绩效目标。'

+0

有趣的想法 –

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

INDEX(idhotel, idhall, date) 

VIEWs是语法糖;他们不提高表现;有时它们比等效的SELECT慢。