2017-10-17 6 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; 

(最初にどのI 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 
; 

私は、これははるかに効率的である読み取るように私はUNION ALL代わりにUNIONしようと試み

(表new_hall_reservationは同じインデックスを有します)。

t_booking_hall_reservationためt_bookingを変更するまあ、元のクエリは、終えることがカレンダービューを不可能にする各々のホールと毎日のために乗算し、1.5秒かかります。

アプリはスパゲティのコードなので、2回繰り返します.t_bookingを超えて1回、その後new_hall_reservationを超えると、何らかの結果が得られません。

このクエリを十分速くするためにビューを調整することはできますか?別のアプローチですか?

おかげ

PS:以下、私は元のクエリを変更し、より少ない私は

+0

'JOIN'は2番目の' SELECT'の一部になっていますか?あるいは、「連合」の結果セットの一部ですか? –

+0

@RickJames、JOINは2番目のSELECTの一部です –

+0

インデックスの内容を知るために、 'SHOW CREATE TABLE'を提供してください。 –

答えて

0

これを変更することは危険、以下で、ある、レガシーアプリケーションを変更する必要がありますコメントに対して長すぎます。

ビューは(ほとんど)パフォーマンスを助けることはありません。はい、クエリが簡単になります。はい、彼らは重要な論理を取り入れています。しかし、いいえ、彼らはパフォーマンスを助けません。

一つの重要な問題は、ビューの実行である - (のMySQLの最新バージョンは、この時に優れていますが)、それは一般的に考慮し、全体的なテーブルでフィルタを取ることはありません。

1つの提案は、かなりの作業である可能性がありますが、ビューを表として実現することです。基になるテーブルが変更されたら、トリガーを使用してt_booking_hall_reservationを変更する必要があります。次に、パフォーマンス目標を達成するためにテーブルにインデックスを作成することができます。「

+0

興味深いアイデア –

0

t_booking、それはVIEWでない限り、

INDEX(idhotel, idhall, date) 

VIEWsはシンタックスシュガーある必要があります。パフォーマンスを向上させるものではありません。時にはそれは同等のものより遅い場合がありますSELECT