оптимизација: Optimizirinani views.sql

File Optimizirinani views.sql, 10.4 KB (added by 231233, 2 days ago)
Line 
1CREATE INDEX IF NOT EXISTS idx_ticket_screening ON TICKET(screening_id);
2CREATE INDEX IF NOT EXISTS idx_ticket_user ON TICKET(user_id);
3CREATE INDEX IF NOT EXISTS idx_ticket_seat ON TICKET(seat_id);
4CREATE INDEX IF NOT EXISTS idx_screening_movie ON SCREENING(movie_id);
5CREATE INDEX IF NOT EXISTS idx_screening_hall ON SCREENING(cinemahall_id);
6CREATE INDEX IF NOT EXISTS idx_screening_date ON SCREENING("date");
7CREATE INDEX IF NOT EXISTS idx_screening_time ON SCREENING("time");
8CREATE INDEX IF NOT EXISTS idx_review_movie ON REVIEW(movie_id);
9CREATE INDEX IF NOT EXISTS idx_reservation_status ON RESERVATION(status);
10CREATE INDEX IF NOT EXISTS idx_purchased_product_ticket ON PURCHASED_PRODUCT(ticket_id);
11CREATE INDEX IF NOT EXISTS idx_purchased_product_product ON PURCHASED_PRODUCT(product_id);
12CREATE INDEX IF NOT EXISTS idx_movie_genre_movie ON MOVIE_GENRE(movie_id);
13CREATE INDEX IF NOT EXISTS idx_movie_genre_genre ON MOVIE_GENRE(genre_id);
14
15DROP MATERIALIZED VIEW IF EXISTS mat_movie_revenue CASCADE;
16DROP MATERIALIZED VIEW IF EXISTS mat_most_watched_genre CASCADE;
17DROP MATERIALIZED VIEW IF EXISTS mat_busiest_months CASCADE;
18DROP MATERIALIZED VIEW IF EXISTS mat_cinema_revenue CASCADE;
19DROP MATERIALIZED VIEW IF EXISTS mat_hall_occupancy CASCADE;
20DROP MATERIALIZED VIEW IF EXISTS mat_top_products CASCADE;
21DROP MATERIALIZED VIEW IF EXISTS mat_promotion_impact CASCADE;
22DROP MATERIALIZED VIEW IF EXISTS mat_reservation_status CASCADE;
23DROP MATERIALIZED VIEW IF EXISTS mat_popular_time_slots CASCADE;
24DROP MATERIALIZED VIEW IF EXISTS mat_product_vs_ticket_revenue CASCADE;
25DROP MATERIALIZED VIEW IF EXISTS mat_morning_vs_evening CASCADE;
26DROP MATERIALIZED VIEW IF EXISTS mat_movie_review_stats CASCADE;
27DROP MATERIALIZED VIEW IF EXISTS mat_genre_review_stats CASCADE;
28
29-- 1. Priod po film
30CREATE MATERIALIZED VIEW mat_movie_revenue AS
31SELECT m.title,
32 COUNT(t.ticket_id) AS total_tickets,
33 SUM(t.price) AS total_revenue,
34 ROUND(AVG(t.price)::numeric, 2) AS avg_ticket_price
35FROM MOVIE m
36JOIN SCREENING s ON s.movie_id = m.movie_id
37JOIN TICKET t ON t.screening_id = s.screening_id
38GROUP BY m.title
39ORDER BY total_revenue DESC;
40
41-- 2. Najgledan zanr (bez DISTINCT i bez LEFT JOIN)
42CREATE MATERIALIZED VIEW mat_most_watched_genre AS
43SELECT g.name AS genre,
44 COUNT(t.ticket_id) AS total_tickets,
45 SUM(t.price) AS total_revenue
46FROM GENRE g
47JOIN MOVIE_GENRE mg ON mg.genre_id = g.genre_id
48JOIN SCREENING s ON s.movie_id = mg.movie_id
49JOIN TICKET t ON t.screening_id = s.screening_id
50GROUP BY g.name
51ORDER BY total_tickets DESC;
52
53-- 3. Najaktivni periodi po mesec
54CREATE MATERIALIZED VIEW mat_busiest_months AS
55SELECT EXTRACT(YEAR FROM s.date)::int AS year,
56 EXTRACT(MONTH FROM s.date)::int AS month,
57 COUNT(t.ticket_id) AS total_tickets,
58 SUM(t.price) AS total_revenue
59FROM SCREENING s
60JOIN TICKET t ON t.screening_id = s.screening_id
61GROUP BY year, month
62ORDER BY year, month;
63
64-- 4. Priod po kino
65CREATE MATERIALIZED VIEW mat_cinema_revenue AS
66SELECT c.name AS cinema,
67 ci.name AS city,
68 COUNT(t.ticket_id) AS total_tickets,
69 SUM(t.price) AS total_revenue,
70 ROUND(AVG(t.price)::numeric, 2) AS avg_ticket_price
71FROM CINEMA c
72JOIN CITY ci ON ci.city_id = c.city_id
73JOIN CINEMA_HALL ch ON ch.cinema_id = c.cinema_id
74JOIN SCREENING s ON s.cinemahall_id = ch.cinemahall_id
75JOIN TICKET t ON t.screening_id = s.screening_id
76GROUP BY c.name, ci.name
77ORDER BY total_revenue DESC;
78
79-- 5. Popolnetost na sali (bez COUNT DISTINCT)
80CREATE MATERIALIZED VIEW mat_hall_occupancy AS
81SELECT ch.description AS hall,
82 c.name AS cinema,
83 ch.capacity,
84 COUNT(t.ticket_id) AS total_tickets_sold
85FROM CINEMA_HALL ch
86JOIN CINEMA c ON c.cinema_id = ch.cinema_id
87JOIN SCREENING s ON s.cinemahall_id = ch.cinemahall_id
88JOIN TICKET t ON t.screening_id = s.screening_id
89GROUP BY ch.description, c.name, ch.capacity
90ORDER BY total_tickets_sold DESC;
91
92-- 6. Najprodavani proizvodi
93CREATE MATERIALIZED VIEW mat_top_products AS
94SELECT p.name AS product,
95 p.unit,
96 p.price AS unit_price,
97 SUM(pp.numbers) AS total_quantity_sold,
98 SUM(pp.numbers * p.price) AS total_revenue
99FROM PRODUCT p
100JOIN PURCHASED_PRODUCT pp ON pp.product_id = p.product_id
101GROUP BY p.name, p.unit, p.price
102ORDER BY total_quantity_sold DESC;
103
104-- 7. Promocii vs priod
105CREATE MATERIALIZED VIEW mat_promotion_impact AS
106SELECT pr.name AS promotion,
107 pr.discount AS discount_percent,
108 COUNT(t.ticket_id) AS total_tickets,
109 SUM(t.price) AS revenue_with_promotion,
110 ROUND(AVG(t.price)::numeric, 2) AS avg_ticket_price
111FROM PROMOTION pr
112JOIN SCREENING s ON s.screening_id = pr.screening_id
113JOIN TICKET t ON t.screening_id = s.screening_id
114GROUP BY pr.name, pr.discount
115ORDER BY total_tickets DESC;
116
117-- 8. Rezervacii po status
118CREATE MATERIALIZED VIEW mat_reservation_status AS
119SELECT status,
120 COUNT(*) AS total_reservations,
121 ROUND(COUNT(*) * 100.0 / SUM(COUNT(*)) OVER (), 2) AS percentage
122FROM RESERVATION
123GROUP BY status
124ORDER BY total_reservations DESC;
125
126-- 9. Popularni termini
127CREATE MATERIALIZED VIEW mat_popular_time_slots AS
128SELECT s.time AS time_slot,
129 CASE
130 WHEN s.time < '13:00:00' THEN 'Morning'
131 WHEN s.time < '18:00:00' THEN 'Afternoon'
132 ELSE 'Evening'
133 END AS period,
134 COUNT(t.ticket_id) AS total_tickets,
135 SUM(t.price) AS total_revenue,
136 ROUND(AVG(t.price)::numeric, 2) AS avg_ticket_price
137FROM SCREENING s
138JOIN TICKET t ON t.screening_id = s.screening_id
139GROUP BY s.time
140ORDER BY total_tickets DESC;
141
142-- 10. Proizvodi vs tiketi priod
143CREATE MATERIALIZED VIEW mat_product_vs_ticket_revenue AS
144SELECT 'Tickets' AS revenue_source, SUM(t.price) AS total_revenue
145FROM TICKET t
146UNION ALL
147SELECT 'Products', SUM(pp.numbers * p.price)
148FROM PURCHASED_PRODUCT pp
149JOIN PRODUCT p ON p.product_id = pp.product_id;
150
151-- 11. Utro vs Vecer priod
152CREATE MATERIALIZED VIEW mat_morning_vs_evening AS
153SELECT
154 CASE
155 WHEN s.time < '13:00:00' THEN 'Morning'
156 WHEN s.time < '18:00:00' THEN 'Afternoon'
157 ELSE 'Evening'
158 END AS period,
159 COUNT(t.ticket_id) AS total_tickets,
160 SUM(t.price) AS total_revenue,
161 ROUND(AVG(t.price)::numeric, 2) AS avg_ticket_price
162FROM SCREENING s
163JOIN TICKET t ON t.screening_id = s.screening_id
164GROUP BY period
165ORDER BY total_revenue DESC;
166
167-- 12. Review statistika po film
168CREATE MATERIALIZED VIEW mat_movie_review_stats AS
169SELECT m.title,
170 COUNT(r.review_id) AS total_reviews,
171 ROUND(AVG(r.rating)::numeric,2) AS avg_rating,
172 MAX(r.rating) AS max_rating,
173 MIN(r.rating) AS min_rating
174FROM MOVIE m
175JOIN REVIEW r ON r.movie_id = m.movie_id
176GROUP BY m.title
177ORDER BY avg_rating DESC;
178
179-- 13. Review statistika po zanr
180CREATE MATERIALIZED VIEW mat_genre_review_stats AS
181SELECT g.name AS genre,
182 COUNT(r.review_id) AS total_reviews,
183 ROUND(AVG(r.rating)::numeric,2) AS avg_rating
184FROM GENRE g
185JOIN MOVIE_GENRE mg ON mg.genre_id = g.genre_id
186JOIN REVIEW r ON r.movie_id = mg.movie_id
187GROUP BY g.name
188ORDER BY avg_rating DESC;
189
190--------------------------------
191
192--------------------------------
193DO $$
194DECLARE
195 start_time TIMESTAMPTZ;
196 end_time TIMESTAMPTZ;
197BEGIN
198 -- 1
199 start_time := clock_timestamp();
200 PERFORM * FROM mat_movie_revenue;
201 RAISE NOTICE 'mat_movie_revenue: % ms', EXTRACT(MILLISECONDS FROM clock_timestamp()-start_time);
202
203 -- 2
204 start_time := clock_timestamp();
205 PERFORM * FROM mat_most_watched_genre;
206 RAISE NOTICE 'mat_most_watched_genre: % ms', EXTRACT(MILLISECONDS FROM clock_timestamp()-start_time);
207
208 -- 3
209 start_time := clock_timestamp();
210 PERFORM * FROM mat_busiest_months;
211 RAISE NOTICE 'mat_busiest_months: % ms', EXTRACT(MILLISECONDS FROM clock_timestamp()-start_time);
212
213 -- 4
214 start_time := clock_timestamp();
215 PERFORM * FROM mat_cinema_revenue;
216 RAISE NOTICE 'mat_cinema_revenue: % ms', EXTRACT(MILLISECONDS FROM clock_timestamp()-start_time);
217
218 -- 5
219 start_time := clock_timestamp();
220 PERFORM * FROM mat_hall_occupancy;
221 RAISE NOTICE 'mat_hall_occupancy: % ms', EXTRACT(MILLISECONDS FROM clock_timestamp()-start_time);
222
223 -- 6
224 start_time := clock_timestamp();
225 PERFORM * FROM mat_top_products;
226 RAISE NOTICE 'mat_top_products: % ms', EXTRACT(MILLISECONDS FROM clock_timestamp()-start_time);
227
228 -- 7
229 start_time := clock_timestamp();
230 PERFORM * FROM mat_promotion_impact;
231 RAISE NOTICE 'mat_promotion_impact: % ms', EXTRACT(MILLISECONDS FROM clock_timestamp()-start_time);
232
233 -- 8
234 start_time := clock_timestamp();
235 PERFORM * FROM mat_reservation_status;
236 RAISE NOTICE 'mat_reservation_status: % ms', EXTRACT(MILLISECONDS FROM clock_timestamp()-start_time);
237
238 -- 9
239 start_time := clock_timestamp();
240 PERFORM * FROM mat_popular_time_slots;
241 RAISE NOTICE 'mat_popular_time_slots: % ms', EXTRACT(MILLISECONDS FROM clock_timestamp()-start_time);
242
243 -- 10
244 start_time := clock_timestamp();
245 PERFORM * FROM mat_product_vs_ticket_revenue;
246 RAISE NOTICE 'mat_product_vs_ticket_revenue: % ms', EXTRACT(MILLISECONDS FROM clock_timestamp()-start_time);
247
248 -- 11
249 start_time := clock_timestamp();
250 PERFORM * FROM mat_morning_vs_evening;
251 RAISE NOTICE 'mat_morning_vs_evening: % ms', EXTRACT(MILLISECONDS FROM clock_timestamp()-start_time);
252
253 -- 12
254 start_time := clock_timestamp();
255 PERFORM * FROM mat_movie_review_stats;
256 RAISE NOTICE 'mat_movie_review_stats: % ms', EXTRACT(MILLISECONDS FROM clock_timestamp()-start_time);
257
258 -- 13
259 start_time := clock_timestamp();
260 PERFORM * FROM mat_genre_review_stats;
261 RAISE NOTICE 'mat_genre_review_stats: % ms', EXTRACT(MILLISECONDS FROM clock_timestamp()-start_time);
262END $$;