-- DDL CREATE TABLE transactions ( customer_id INT NOT NULL, order_id INT NOT NULL UNIQUE, revenue DECIMAL(10,2) NOT NULL, PRIMARY KEY (order_id) );
-- Test Data INSERT INTO transactions (customer_id, order_id, revenue) VALUES (101, 1001, 150.75), (101, 1002, 200.00), (101, 1003, 75.20), (101, 1004, 300.50), (102, 2001, 50.00), (102, 2002, 120.99), (102, 2003, 80.10), (103, 3001, 400.00), (103, 3002, 100.00), (103, 3003, 500.00), (104, 4001, 25.00), (104, 4002, 35.00), (105, 5001, 99.99);
-- SQL Query WITH RankedOrders AS ( SELECT customer_id, order_id, revenue, ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY revenue DESC) as rn FROM transactions ) SELECT customer_id, order_id, revenue FROM RankedOrders WHERE rn <= 3 ORDER BY customer_id, rn;
-- Expected Query Plan Notes The query plan will typically involve a WindowAgg operation. The PARTITION BY customer_id clause requires data to be grouped by customer_id. Following this, the ORDER BY revenue DESC within each partition necessitates a sort operation on revenue for each customer_id group. This sorting step is often the most resource-intensive part, especially on large datasets. After ranks are assigned, a Filter step prunes rows where rn exceeds 3. The final ORDER BY customer_id, rn may introduce another sort. Without an appropriate index, a full table scan followed by a large sort will occur before the window function.
-- Index Recommendation To optimize this query, an index on (customer_id, revenue DESC) is recommended.
CREATE INDEX idx_customer_revenue ON transactions (customer_id, revenue DESC);
This index significantly improves performance by:
- Partitioning Support:
customer_id in the index directly supports the PARTITION BY customer_id clause, allowing efficient grouping. - Pre-sorted Data: Including
revenue DESC in the index means data within each customer_id group is already sorted as required by the window function's ORDER BY clause. This largely eliminates expensive sort operations during the WindowAgg phase, which is critical for large tables.