使用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:欠我修改原始查询,我需要修改遗留应用程序,这是在少之更少,风险修改
这是太长评论。
视图(几乎)永远不会帮助性能。是的,他们使查询更简单。是的,它们包含了重要的逻辑。但是,不,他们没有帮助表现。
一个关键问题是视图的执行 - 它通常不考虑整个表中的过滤器(虽然最新版本的MySQL在这方面更好)。
一个建议 - 这可能是一个相当的工作 - 是实现视图作为一个表。当基础表发生变化时,您需要使用触发器更改t_booking_hall_reservation
。然后,您可以在表格上创建索引以实现您的绩效目标。'
有趣的想法 –
t_booking,除非它是一个VIEW
,需要
INDEX(idhotel, idhall, date)
VIEWs
是语法糖;他们不提高表现;有时它们比等效的SELECT
慢。
'JOIN'应该是第二个'SELECT'的一部分吗?还是'UNION'结果集的一部分? –
@RickJames,JOIN是第二个SELECT的一部分 –
请提供'SHOW CREATE TABLE',以便我们知道索引是什么。 –