Changes between Initial Version and Version 1 of Indexes


Ignore:
Timestamp:
01/29/26 22:52:58 (10 days ago)
Author:
233194
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Indexes

    v1 v1  
     1== Indexes and performance analysis ==
     2
     3Here we will cover the indexes that are not automatically created with PK/UK constraints, but would significantly improve performance in PC Forge. The focus is on the most frequent queries, JOIN operations and critical business scenarios. \\
     4With these indexes: \\
     5-Most frequent searches are covered (including build names, component names) \\
     6-Filtering by approval status and build dates is optimized \\
     7-JOIN operations between builds and components are faster \\
     8-Rating and favorite calculations are efficient \\
     9-Component type browsing is optimized \\
     10
     11== Scenario 1: Approved Builds Browsing and Filtering ==
     12Users frequently browse approved builds, filter them by name and sort by price, date or rating. This involves filtering by is_approved, searching by name and sorting by created_at or total_price. \\
     13Optimization: A composite index on is_approved and created_at speeds up the most common query pattern. Adding total_price allows for efficient sorting without additional table lookups. \\
     14{{{
     15CREATE INDEX IF NOT EXISTS idx_build_approved_date
     16ON build(is_approved, created_at DESC);
     17
     18CREATE INDEX IF NOT EXISTS idx_build_approved_price
     19ON build(is_approved, total_price DESC);
     20
     21CREATE INDEX IF NOT EXISTS idx_build_name_search
     22ON build(name);
     23}}}
     24
     25is_approved is a low-cardinality column (TRUE/FALSE), while both created_at and total_price are high-cardinality columns often used for ORDER BY, so that's why this combination is optimal. \\
     26
     27== Scenario 2: User Dashboard - Builds and Favorites ==
     28The user dashboard displays builds created by the user and also builds they've favorited, created by other users. This requires frequent lookups by user_id in both build and favorite_build tables, often with rating aggregations. \\
     29Optimization: Indexes on user_id in both tables, plus composite indexes for the JOIN operations between builds and ratings. \\
     30{{{
     31CREATE INDEX IF NOT EXISTS idx_build_user_id
     32ON build(user_id);
     33
     34CREATE INDEX IF NOT EXISTS idx_favorite_build_user_id
     35ON favorite_build(user_id);
     36
     37CREATE INDEX IF NOT EXISTS idx_rating_build_build_id
     38ON rating_build(build_id);
     39}}}
     40
     41== Scenario 3: Build Components and Compatibility Checking ==
     42When users view build details or add components to builds, the application performs frequent JOIN operations between build_component and components. Compatibility checking also requires lookups by component type and specific attributes (like socket, TDP, form factor, length). \\
     43Optimization: Composite indexes on the junction table and component type filtering. \\
     44{{{
     45CREATE INDEX IF NOT EXISTS idx_build_component_build_id
     46ON build_component(build_id);
     47
     48CREATE INDEX IF NOT EXISTS idx_build_component_component_id
     49ON build_component(component_id);
     50
     51CREATE INDEX IF NOT EXISTS idx_components_type_price
     52ON components(type, price DESC);
     53
     54CREATE INDEX IF NOT EXISTS idx_components_name_search
     55ON components(name);
     56}}}
     57The composite index (type, price DESC) is really useful when it comes to component browsing dialogs, because they filter by type and sort by price by default. \\
     58
     59== Scenario 4: Admin Panel - Pending Approvals ==
     60Admins frequently check for pending builds and suggestions. This requires filtering by is_approved = FALSE for builds and status = 'pending' for component suggestions. \\
     61Optimization: Indexes on status columns with date ordering for priority sorting. \\
     62{{{
     63CREATE INDEX IF NOT EXISTS idx_build_pending_date
     64ON build(is_approved, created_at DESC)
     65WHERE is_approved = FALSE;
     66
     67CREATE INDEX IF NOT EXISTS idx_suggestions_status
     68ON suggestions(status);
     69
     70CREATE INDEX IF NOT EXISTS idx_suggestions_user_id
     71ON suggestions(user_id);
     72}}}
     73The partial index on build with WHERE is_approved = FALSE is smaller and more efficient, since admins only care about unapproved builds. //
     74
     75== Scenario 5: Reviews and User Authentication ==
     76Users leave reviews on builds, commenting their likes and dislikes, and with that the application frequently looks up usernames for authentication and display purposes. \\
     77Optimization: Indexes for review lookups and username searches. \\
     78{{{
     79CREATE INDEX IF NOT EXISTS idx_review_build_id
     80ON review(build_id);
     81
     82CREATE INDEX IF NOT EXISTS idx_review_user_id
     83ON review(user_id);
     84
     85CREATE INDEX IF NOT EXISTS idx_users_username
     86ON users(username);
     87
     88CREATE INDEX IF NOT EXISTS idx_users_email
     89ON users(email);
     90}}}
     91
     92username and email are both UNIQUE, but explicit indexes improve login query performance and case-insensitive searches if needed. \\
     93
     94== Scenario 6: Component Compatibility - Socket and Form Factor Matching ==
     95When users add components to their builds, the compatibility logic frequently queries CPU sockets, motherboard sockets and cooler compatibility. \\
     96Optimization: Indexes on compatibility-critical columns. \\
     97{{{
     98CREATE INDEX IF NOT EXISTS idx_cpu_socket
     99ON cpu(socket);
     100
     101CREATE INDEX IF NOT EXISTS idx_motherboard_socket
     102ON motherboard(socket);
     103
     104CREATE INDEX IF NOT EXISTS idx_cooler_sockets_socket
     105ON cooler_cpu_sockets(socket);
     106
     107CREATE INDEX IF NOT EXISTS idx_motherboard_form_factor
     108ON motherboard(form_factor);
     109}}}
     110
     111== Testing with EXPLAIN ANALYZE ==
     112Example test for scenario 4:
     113{{{
     114EXPLAIN (ANALYZE, BUFFERS)
     115SELECT b.id, b.name, b.created_at, b.total_price, u.username
     116FROM build b
     117JOIN users u ON u.id = b.user_id
     118WHERE b.is_approved = FALSE
     119ORDER BY b.created_at DESC
     120LIMIT 50;
     121}}}
     122
     123== Performance Comparison ==
     124
     125=== Without partial index: ===
     126Index Scan using idx_build_approved_date on build b
     127  Index Cond: (is_approved = false)
     128  Buffers: shared hit=150
     129Execution Time: 0.351 ms \\
     130
     131=== With partial index: ===
     132Index Scan using idx_build_pending_date on build b
     133  Buffers: shared hit=68 read=2
     134Execution Time: 0.219 ms \\
     135
     136Result: The partial index improved query performance by dropping the execution time from 0.351ms to 0.219ms. Partial indexes are more efficient for frequently filtered subsets of data, so that's why they are ideal for this admin queries that only target pending builds.
     137
     138
     139
     140
     141