Changes between Version 5 and Version 6 of OtherTopics


Ignore:
Timestamp:
09/11/26 10:39:13 (6 hours ago)
Author:
232012
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • OtherTopics

    v5 v6  
    7272== Scenario 2 - Slow Moving Products
    7373
     74{{{#!div style="text-align: justify; width: 100%;"
     75
    7476==== Without indexes
    7577
     
    126128{{{idx_orders_status_purchase_date}}} was successfully used as an Index Only Scan and improved the filtering of orders by status and purchase date.
    127129The query improved by approximately 26.65%, while the existing {{{order_products_pk}}} index continued to support the join efficiently.
     130
     131}}}
     132
     133== Scenario 3 - Impact of Admin Discounts on Sales Numbers
     134
     135{{{#!div style="text-align: justify; width: 100%;"
     136
     137==== Without indexes
     138
     139The query was tested on approximately 25,017 orders and 75,021 order-product records. Before indexing, PostgreSQL used sequential scans on both {{{orders}}} and {{{order_products}}} while calculating the 30-day periods before and after each discount.
     140
     141{{{
     142Seq Scan on order_products
     143rows=75021
     144
     145Seq Scan on orders
     146rows=5009
     147Rows Removed by Filter: 20008
     148}}}
     149
     150The query was executed 10 times and the average execution time without indexes was: **103.004 ms**
     151
     152==== Indexes
     153
     154{{{
     155CREATE INDEX idx_order_products_product_order
     156ON project.order_products (product_id, order_id)
     157INCLUDE (quantity, price_at_purchase);
     158
     159CREATE INDEX idx_orders_status_purchase_date
     160ON project.orders (status, purchase_date, order_id);
     161
     162ANALYZE project.order_products;
     163ANALYZE project.orders;
     164}}}
     165
     166* {{{idx_order_products_product_order}}} was tested to support lookups of order products by {{{product_id}}} and provide the quantity and purchase price required by the aggregation.
     167
     168* {{{idx_orders_status_purchase_date}}} targets the order status filter and includes the purchase date and {{{order_id}}} needed for the sales-period joins.
     169
     170==== With indexes
     171
     172PostgreSQL used:
     173
     174{{{
     175Index Only Scan using idx_orders_status_purchase_date on orders
     176Heap Fetches: 0
     177}}}
     178
     179The index was used for both the pre-promotion and post-promotion order lookups.
     180
     181However, {{{idx_order_products_product_order}}} was not used. PostgreSQL continued using:
     182
     183{{{
     184Seq Scan on order_products
     185}}}
     186
     187because scanning the table and performing the hash joins was estimated to be cheaper for the current data distribution.
     188
     189The query was executed 10 times with both indexes present and the average execution time was: **97.710 ms**
     190
     191The unused {{{idx_order_products_product_order}}} index was removed after testing.
     192
     193==== Performance comparison and conclusion
     194
     195{{{
     196Without indexes: 103.004 ms
     197With indexes: 97.710 ms
     198Improvement: 5.14%
     199}}}
     200
     201* {{{idx_orders_status_purchase_date}}} was successfully used as an Index Only Scan in both the pre-promotion and post-promotion parts of the query.
     202
     203* {{{idx_order_products_product_order}}} was not used by the optimizer and was removed.
     204
     205}}}
     206
     207== Scenario 4 - Customer Habits and Points Spending
     208
     209==== Without indexes
     210
     211The query was tested on approximately 25,017 orders and 75,021 order-product records. Before indexing, PostgreSQL used a sequential scan on {{{orders}}} and scanned all {{{order_products}}} records to calculate order totals.
     212
     213{{{
     214Seq Scan on orders
     215rows=5009
     216Rows Removed by Filter: 20008
     217
     218Seq Scan on order_products
     219rows=75021
     220}}}
     221
     222The {{{order_products}}} aggregation also required temporary disk usage:
     223
     224{{{
     225HashAggregate
     226Batches: 5
     227Disk Usage: 760kB
     228}}}
     229
     230The query was executed 10 times and the average execution time without indexes was: **93.895 ms**
     231
     232==== Indexes
     233
     234{{{
     235CREATE INDEX idx_orders_status_purchase_date
     236ON project.orders (status, purchase_date, order_id);
     237
     238ANALYZE project.orders;
     239}}}
     240
     241The index targets the {{{status}}} and {{{purchase_date}}} filters on {{{orders}}} and includes {{{order_id}}} for the join with aggregated order totals.
     242
     243==== With indexes
     244
     245After indexing, PostgreSQL used:
     246
     247{{{
     248Bitmap Index Scan on idx_orders_status_purchase_date
     249
     250Bitmap Heap Scan on orders
     251}}}
     252
     253This replaced the sequential scan on {{{orders}}}.
     254
     255However, {{{order_products}}} was still processed using:
     256
     257{{{
     258Seq Scan on order_products
     259rows=75021
     260}}}
     261
     262because the query needs to aggregate essentially the whole {{{order_products}}} table to calculate total spend per order.
     263
     264The query was executed 10 times and the average execution time with indexes was: **90.547 ms**
     265
     266==== Performance comparison and conclusion
     267
     268{{{
     269Without indexes: 93.895 ms
     270With indexes: 90.547 ms
     271Improvement: 3.57%
     272}}}
     273
     274* {{{idx_orders_status_purchase_date}}} was successfully used through a Bitmap Index Scan and reduced the cost of filtering orders.
     275
     276* The overall improvement was approximately 3.57% because the main remaining cost is the full aggregation of {{{order_products}}}, which still requires a sequential scan and temporary disk usage.
    128277
    129278== Security