PostgreSQL EXPLAIN Command

Understanding the PostgreSQL EXPLAIN Command: Decode Your Query Plan


The EXPLAIN command in PostgreSQL is your go-to tool for inspecting query performance. This robust command provides insights into the query planner’s decision-making process, helping you understand and optimize your queries. Let’s break it down.

What is the EXPLAIN Command?

The EXPLAIN command shows the query plan of a statement which helps to analyze and optimize queries. PostgreSQL query plans contain vital information about:

  • Execution order of table scans
  • Join types used
  • Estimated cost and time of operations

Basic Syntax

The most basic form of the EXPLAIN command is:

EXPLAIN your_query_here;

For example, to examine a simple SELECT query on the tv_series table, you’d run:

EXPLAIN SELECT * FROM tv_series WHERE genre = 'Drama';

How to Read and Understand the Query Plan

Here’s a quick breakdown of key terms you might encounter in the output:

  • Seq Scan: Sequential scan. Scans each row one by one.
  • Index Scan: Uses an index to improve query speed.
  • Cost: Estimated cost of the operation, where lower is better.
  • Filter: A WHERE clause or similar query filter.

Understanding these terms can help you identify bottlenecks and come up with optimization strategies.



By adding the ANALYZE keyword, you can execute the query and get real-time statistics:

EXPLAIN ANALYZE SELECT * FROM tv_series WHERE genre = 'Drama';

When to Use: It’s best to use ANALYZE on a development database. Since it actually executes the query, it can make changes to your data.


When using prepared statements, the EXECUTE flag helps you get a query plan based on real parameter values:

PREPARE my_query(text) AS SELECT * FROM tv_series WHERE genre = $1;
EXPLAIN EXECUTE my_query('Drama');

When to Use: Use this option when working with prepared statements.

How to Read and Interpret a Query Plan

For the purpose of demonstration, let’s consider a query plan on the tv_series table:

EXPLAIN SELECT * FROM tv_series WHERE genre = 'Drama';

Here’s a simplified example of what the output might look like :

Seq Scan on tv_series (cost=0.00..35.50 rows=38 width=72)
Filter: (genre = ‘Drama’::text)

actual values might differ

Decoding the Query Plan

Let’s break down the output into manageable pieces:

  1. Seq Scan on tv_series: This shows that a sequential scan is being used on the tv_series table. That means PostgreSQL scans each row one by one.

  2. cost=0.00..35.50: This provides the estimated cost range of the scan. It starts at 0 and goes up to 35.50. Lower costs are generally better, but this isn’t an absolute measure. It’s used to compare different query plans.

  3. rows=38: This is the estimated number of rows that will be returned. The query planner uses statistics to make this estimate.

  4. width=72: This represents the estimated average width of the rows returned, in bytes.

  5. Filter: (genre = ‘Drama’::text): This shows that a filter is being applied to the rows based on the genre.


  • Seq Scan: Indicates the need for an index, as sequential scans are not usually the most efficient.
  • Cost and Rows: Useful for understanding the estimated load of the query.
  • Filter: Tells you what conditions are applied, useful for ensuring that your WHERE clauses are acting as you expect.

Common Errors and Solutions

Error Message:

ERROR: EXPLAIN ANALYZE is not supported for utility commands


You used EXPLAIN ANALYZE with a non-SELECT query.


  • For utility commands like CREATE TABLE, simply use EXPLAIN without the ANALYZE keyword.

Best Practices and Tips

  • Start with a plain EXPLAIN before moving on to ANALYZE or EXECUTE.
  • Be cautious with EXPLAIN ANALYZE, especially on a production database as it actually runs the query.
  • Use it in tandem with other performance tools like pg_stat_statements for a comprehensive analysis.
  • If you’re consistently seeing Seq Scan and you’re querying on that column frequently, consider adding an index.
  • Take the rows and cost values as ballpark figures, not absolute truths. Always test and analyze your queries in a real-world context.


The EXPLAIN command is a mighty tool for query optimization. Now that you understand how to read query plans, when to use ANALYZE and EXECUTE, and how to interpret common errors, you’re ready to tackle performance bottlenecks in your PostgreSQL queries. Happy optimizing!

Leave a Reply