Changes between Initial Version and Version 1 of P9Performance


Ignore:
Timestamp:
01/16/26 23:39:44 (4 days ago)
Author:
193284
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • P9Performance

    v1 v1  
     1= Phase 9 – Database Performance =
     2
     3== Overview ==
     4Database performance ensures fast, scalable queries as the Wedding Planner system grows. Even in a medium-size database, the number of guests, events and bookings can increase quickly, which leads to slower reports and long waiting times if queries are not optimized.
     5
     6In this phase we explain practical ways to improve performance in PostgreSQL using indexes, query optimization and query plan analysis (EXPLAIN / EXPLAIN ANALYZE). All examples are connected to our Wedding Planner entities such as weddings, guests, events and RSVPs.
     7
     8== What we cover in this phase ==
     9 * Why and when indexes are needed
     10 * Types of indexes (single-column, composite, partial)
     11 * Query optimization techniques (filters, joins, selecting only needed columns)
     12 * Performance analysis using EXPLAIN and EXPLAIN ANALYZE
     13 * Seq Scan vs Index Scan comparison using real examples
     14 * Performance examples with statuses: PLANNED / CONFIRMED / CANCELLED
     15
     16== Implementation & Examples ==
     17
     18=== 1) Indexes in PostgreSQL ===
     19Indexes allow PostgreSQL to find rows faster, without scanning the entire table (full table scan). They are especially useful when:
     20 * filtering using WHERE
     21 * joining tables using JOIN
     22 * sorting results using ORDER BY
     23 * grouping results using GROUP BY
     24
     25Basic syntax:
     26{{{
     27CREATE INDEX idx_name ON table_name(column);
     28}}}
     29
     30==== Example 1: Index for guests per wedding ====
     31This index improves performance when retrieving all guests for a specific wedding.
     32
     33Tables affected:
     34 * guest
     35
     36SQL:
     37{{{
     38CREATE INDEX idx_guest_wedding ON guest(wedding_id);
     39}}}
     40
     41Reason:
     42Guest lists are frequently accessed in the system (wedding dashboard, RSVP pages, attendance lists). Without an index, PostgreSQL may scan the whole guest table.
     43
     44==== Example 2: Composite partial index for active events ====
     45Instead of indexing all rows (including cancelled ones), we index only active events (PLANNED or CONFIRMED). This makes the index smaller and faster.
     46
     47Tables affected:
     48 * event
     49
     50SQL:
     51{{{
     52CREATE INDEX idx_event_wedding_status_date_time
     53ON event (wedding_id, date, start_time)
     54WHERE status IN ('PLANNED', 'CONFIRMED');
     55}}}
     56
     57Benefits:
     58 * smaller index -> faster lookups
     59 * skips CANCELLED events
     60 * improves performance for scheduling queries and event timelines
     61
     62---
     63
     64=== 2) Query Optimization ===
     65Query optimization means writing SQL in a way that helps PostgreSQL return results efficiently, with minimal scanned rows and minimal memory usage.
     66
     67Key principles:
     68 * Push filters early (WHERE conditions reduce data before joins)
     69 * Join in the right order (smaller filtered datasets joined first)
     70 * Use indexes effectively (WHERE and JOIN should match indexed columns)
     71 * Avoid SELECT * (select only the needed columns)
     72 * Use FILTER() in aggregates (cleaner and often faster than CASE WHEN)
     73
     74==== Example: Optimized RSVP summary report ====
     75This query returns a summary per wedding and counts confirmed/cancelled responses efficiently.
     76
     77{{{
     78SELECT
     79    w.wedding_id,
     80    COUNT(g.guest_id) AS total_guests,
     81    COUNT(r.status) FILTER (WHERE r.status = 'CONFIRMED') AS confirmed,
     82    COUNT(r.status) FILTER (WHERE r.status = 'CANCELLED') AS cancelled
     83FROM wedding w
     84JOIN guest g ON w.wedding_id = g.wedding_id
     85LEFT JOIN event_rsvp r ON g.guest_id = r.guest_id
     86GROUP BY w.wedding_id;
     87}}}
     88
     89Why this is optimized:
     90 * FILTER avoids multiple CASE expressions
     91 * joins only needed tables
     92 * works better together with indexes (e.g., idx_guest_wedding)
     93
     94=== 3) Performance Analysis (EXPLAIN / EXPLAIN ANALYZE) ===
     95EXPLAIN shows how PostgreSQL plans to execute a query (scan type, join strategy, estimated costs).
     96EXPLAIN ANALYZE executes the query and provides real execution time and row statistics.
     97
     98Most important things to look for:
     99 * Seq Scan (slow when table grows)
     100 * Index Scan (fast, uses index)
     101 * join algorithms (Hash Join / Nested Loop)
     102 * execution time before vs after optimization
     103
     104---
     105
     106==== Example: Before/After Index (Seq Scan vs Index Scan) ====
     107
     108Before index (Sequential Scan):
     109{{{
     110EXPLAIN ANALYZE
     111SELECT *
     112FROM event
     113WHERE wedding_id = 3
     114  AND status IN ('PLANNED', 'CONFIRMED');
     115}}}
     116
     117Mini output (example):
     118{{{
     119Seq Scan on event  (cost=0.00..1450.00 rows=120 width=48)
     120  Filter: ((wedding_id = 3) AND (status = ANY '{PLANNED,CONFIRMED}'::text[]))
     121Execution Time: 12.334 ms
     122}}}
     123
     124Explanation:
     125 * Seq Scan means PostgreSQL scans the entire event table
     126 * this becomes very slow when events grow in number
     127
     128After creating partial index:
     129{{{
     130EXPLAIN ANALYZE
     131SELECT *
     132FROM event
     133WHERE wedding_id = 3
     134  AND status IN ('PLANNED', 'CONFIRMED');
     135}}}
     136
     137Mini output (example):
     138{{{
     139Index Scan using idx_event_wedding_status_date_time on event
     140  (cost=0.25..12.50 rows=20 width=48)
     141  Index Cond: (wedding_id = 3)
     142Execution Time: 0.423 ms
     143}}}
     144
     145Result:
     146 * Seq Scan -> Index Scan
     147 * execution time reduced significantly
     148 * confirms the index is being used correctly
     149
     150---
     151
     152==== Example: JOIN performance analysis ====
     153This query demonstrates how PostgreSQL executes joins when generating reports.
     154
     155{{{
     156EXPLAIN ANALYZE
     157SELECT w.wedding_id, COUNT(g.guest_id) AS total_guests
     158FROM wedding w
     159JOIN guest g ON w.wedding_id = g.wedding_id
     160GROUP BY w.wedding_id;
     161}}}
     162
     163What to look for:
     164 * join type (Hash Join / Nested Loop)
     165 * whether the guest index is used (idx_guest_wedding)
     166 * number of scanned rows
     167
     168---
     169
     170== Conclusion ==
     171Database performance is essential for fast response times and scalable reports in Wedding Planner. Indexes reduce full table scans and enable PostgreSQL to use Index Scan instead of Seq Scan when filtering weddings, guests, and events.
     172
     173Optimized SQL queries reduce unnecessary work, scanned rows, and memory usage. EXPLAIN ANALYZE is the key tool that confirms whether our indexes and query improvements are actually applied in PostgreSQL. With proper index design and optimized queries, the system remains responsive even as the database grows.