Finding Bottlenecks and Avoiding Over-Optimization via Explain Plans
Performance optimization in a production database is important, but trying to over-optimize can make things more complicated without real improvements.In this post, I’ll share two very basic EXPLAIN ANALYZE outputs from a production system. A user asked us to help optimize these queries. I've changed the table and column names for privacy. We will look at how to spot slow parts of a query, improve performance the right way, and avoid unnecessary tuning.Plan A: Identifying and Resolving a BottleneckExecution Plan A (Before Optimization)
Nested Loop (cost=1000.42..25607.38 rows=1 width=129) (actual time=78.521..90.445 rows=0 loops=1)
-> Gather (cost=1000.00..25598.95 rows=1 width=65) (actual time=78.520..90.443 rows=0 loops=1)
Workers Planned: 2
Workers Launched: 2
-> Parallel Seq Scan on <table_1> e (cost=0.00..24598.85 rows=1 width=65) (actual time=75.351..75.351 rows=0 loops=3)
Filter: ((<column_1>) = '<date_value>'::date) AND ((<column_2>)::text = '<event_type>'::text)
Rows Removed by Filter: <number_removed_rows>
-> Index Scan using <index_name> on <table_2> a (cost=0.42..8.43 rows=1 width=41) (never executed)
Index Cond: ((<column_3>)::text = (<column_4>)::text)
Filter: ((<column_5>)::text = '<default_value>'::text)
Planning Time: 0.466 ms
Execution Time: 90.580 ms