Let us review the below explain plans and understand key terms which will help us in interpreting them.
Seq Scan
Index Scan
Nested Loop
Here are the explain plans for different queries.
Explain plan for query to get number of orders.
Explain plan for query to get number of orders by date.
Explain plan for query to get order details for a given order id.
Explain plan for query to get order and order item details for a given order id.
QUERY PLAN
-----------------------------------------------------------------------------------
Nested Loop (cost=0.29..3427.82 rows=4 width=34)
-> Index Scan using orders_pkey on orders o (cost=0.29..8.31 rows=1 width=26)
Index Cond: (order_id = 2)
-> Seq Scan on order_items oi (cost=0.00..3419.47 rows=4 width=12)
Filter: (order_item_order_id = 2)
(5 rows)
Explain plan for a query with multiple joins
EXPLAIN
SELECT
o.order_date,
d.department_id,
d.department_name,
c.category_name,
p.product_name,
round(sum(oi.order_item_subtotal)::numeric, 2) AS revenue
FROM orders o
JOIN order_items oi
ON o.order_id = oi.order_item_order_id
JOIN products p
ON p.product_id = oi.order_item_product_id
JOIN categories c
ON c.category_id = p.product_category_id
JOIN departments d
ON d.department_id = c.category_department_id
GROUP BY
o.order_date,
d.department_id,
d.department_name,
c.category_id,
c.category_name,
p.product_id,
p.product_name
ORDER BY o.order_date,
revenue DESC;
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------------------
Sort (cost=76368.54..76799.03 rows=172198 width=211)
Sort Key: o.order_date, (round((sum(oi.order_item_subtotal))::numeric, 2)) DESC
-> Finalize GroupAggregate (cost=25958.31..43735.23 rows=172198 width=211)
Group Key: o.order_date, d.department_id, c.category_id, p.product_id
-> Gather Merge (cost=25958.31..39886.09 rows=101293 width=187)
Workers Planned: 1
-> Partial GroupAggregate (cost=24958.30..27490.62 rows=101293 width=187)
Group Key: o.order_date, d.department_id, c.category_id, p.product_id
-> Sort (cost=24958.30..25211.53 rows=101293 width=187)
Sort Key: o.order_date, d.department_id, c.category_id, p.product_id
-> Hash Join (cost=2495.48..7188.21 rows=101293 width=187)
Hash Cond: (c.category_department_id = d.department_id)
-> Hash Join (cost=2472.43..6897.32 rows=101293 width=79)
Hash Cond: (p.product_category_id = c.category_id)
-> Hash Join (cost=2470.13..6609.69 rows=101293 width=63)
Hash Cond: (oi.order_item_product_id = p.product_id)
-> Hash Join (cost=2411.87..6284.70 rows=101293 width=20)
Hash Cond: (oi.order_item_order_id = o.order_id)
-> Parallel Seq Scan on order_items oi (cost=0.00..2279.93 rows=101293 width=16)
-> Hash (cost=1213.83..1213.83 rows=68883 width=12)
-> Seq Scan on orders o (cost=0.00..1213.83 rows=68883 width=12)
-> Hash (cost=41.45..41.45 rows=1345 width=47)
-> Seq Scan on products p (cost=0.00..41.45 rows=1345 width=47)
-> Hash (cost=1.58..1.58 rows=58 width=20)
-> Seq Scan on categories c (cost=0.00..1.58 rows=58 width=20)
-> Hash (cost=15.80..15.80 rows=580 width=112)
-> Seq Scan on departments d (cost=0.00..15.80 rows=580 width=112)
(27 rows)