| | 71 | |
| | 72 | == Scenario 2 - Slow Moving Products |
| | 73 | |
| | 74 | ==== Without indexes |
| | 75 | |
| | 76 | The query was tested on approximately 25,017 orders and 75,021 order-product records. Before indexing, PostgreSQL used a sequential scan on {{{orders}}} to find orders from the last 6 months with a completed status. |
| | 77 | |
| | 78 | {{{ |
| | 79 | Seq Scan on orders |
| | 80 | rows=2549 |
| | 81 | Rows Removed by Filter: 22468 |
| | 82 | }}} |
| | 83 | |
| | 84 | The existing primary-key index on {{{order_products}}} was already used: |
| | 85 | |
| | 86 | {{{ |
| | 87 | Index Only Scan using order_products_pk on order_products |
| | 88 | }}} |
| | 89 | |
| | 90 | The query was executed 10 times and the average execution time without indexes was: **12.125 ms** |
| | 91 | |
| | 92 | ==== Indexes |
| | 93 | |
| | 94 | {{{ |
| | 95 | CREATE INDEX idx_orders_status_purchase_date |
| | 96 | ON project.orders (status, purchase_date, order_id); |
| | 97 | |
| | 98 | ANALYZE project.orders; |
| | 99 | }}} |
| | 100 | |
| | 101 | The index targets the {{{status}}} and {{{purchase_date}}} filters and also includes {{{order_id}}} for the join with {{{order_products}}}. |
| | 102 | |
| | 103 | ==== With indexes |
| | 104 | |
| | 105 | After indexing, PostgreSQL used: |
| | 106 | |
| | 107 | {{{ |
| | 108 | Index Only Scan using idx_orders_status_purchase_date on orders |
| | 109 | Heap Fetches: 0 |
| | 110 | }}} |
| | 111 | |
| | 112 | This replaced the sequential scan on {{{orders}}} and reduced the number of pages that had to be read. |
| | 113 | |
| | 114 | The existing {{{order_products_pk}}} index continued to be used for the join with {{{order_products}}}. |
| | 115 | |
| | 116 | The query was again executed 10 times and the average execution time with indexes was: **8.894 ms** |
| | 117 | |
| | 118 | ==== Performance comparison and conclusion |
| | 119 | |
| | 120 | {{{ |
| | 121 | Without indexes: 12.125 ms |
| | 122 | With indexes: 8.894 ms |
| | 123 | Improvement: 26.65% |
| | 124 | }}} |
| | 125 | |
| | 126 | {{{idx_orders_status_purchase_date}}} was successfully used as an Index Only Scan and improved the filtering of orders by status and purchase date. |
| | 127 | The query improved by approximately 26.65%, while the existing {{{order_products_pk}}} index continued to support the join efficiently. |