SynfraCore
Synfracore
Start Learning
Navigation

Academies

Platform

RoadmapsLabsCertificationsInterviewPYQsAI AssistantCareer
Start Learning Free🗺️ Learning Roadmaps

PostgreSQLInterview Q&A

Most asked interview questions with detailed answers

💬
Verified by practitioners with 5+ years production experience· Updated 2025 · SynfraCore PostgreSQL Team
Expert Content

PostgreSQL Interview Questions

Core Concepts

Q: PostgreSQL vs MySQL — when to choose PostgreSQL?

Choose PostgreSQL when:

Complex queries: window functions, CTEs, lateral joins, recursive queries
Advanced data types needed: JSONB, arrays, hstore, UUID, geometric types, custom types
Full ACID compliance with strict standards (PostgreSQL is more standards-compliant)
Full-text search built in (tsvector, tsquery)
Extensibility: PostGIS for geospatial, pgvector for AI embeddings, TimescaleDB for time-series
Write-heavy workloads (MVCC handles concurrent writes better than MySQL's approach)

Q: Explain MVCC in PostgreSQL.

MVCC (Multi-Version Concurrency Control): Readers never block writers, writers never block readers.

Each row has hidden columns: xmin (transaction that created it) and xmax (transaction that deleted it).

When a row is updated, old version kept for concurrent readers, new version created.

Old versions accumulate → VACUUM cleans them up.

AUTOVACUUM: runs automatically in background. Without it, table bloat and performance degradation.

sql
-- Check autovacuum status
SELECT schemaname, tablename, last_autovacuum, last_autoanalyze 
FROM pg_stat_user_tables;

-- Manual VACUUM
VACUUM ANALYZE orders;   -- Reclaim space, update statistics
VACUUM FULL orders;      -- Full rewrite (locks table, reclaims disk space)

Q: PostgreSQL indexing.

sql
-- B-Tree (default) — equality and range
CREATE INDEX idx_user_email ON users(email);

-- Partial index — only index rows matching condition
CREATE INDEX idx_active_users ON users(email) WHERE active = true;

-- Expression index — index on computed value
CREATE INDEX idx_lower_email ON users(lower(email));
SELECT * FROM users WHERE lower(email) = 'alice@example.com';

-- GIN index — for JSONB, arrays, full-text search
CREATE INDEX idx_tags ON products USING GIN(tags);  -- Array column
CREATE INDEX idx_data ON events USING GIN(metadata JSONB_PATH_OPS);

-- BRIN (Block Range Index) — for large tables with sequential data
CREATE INDEX idx_created ON logs USING BRIN(created_at);

-- pg_trgm — fuzzy search, LIKE queries
CREATE EXTENSION pg_trgm;
CREATE INDEX idx_trgm ON products USING GIN(name gin_trgm_ops);
SELECT * FROM products WHERE name LIKE '%laptop%';  -- Uses GIN trgm index

Q: Window functions — explain with examples.

sql
-- ROW_NUMBER: rank within partition
SELECT 
  name, 
  department, 
  salary,
  ROW_NUMBER() OVER (PARTITION BY department ORDER BY salary DESC) as rank
FROM employees;

-- RANK vs DENSE_RANK
-- RANK: 1,2,2,4 (skips 3 after tie)  DENSE_RANK: 1,2,2,3 (no skip)

-- Running total
SELECT 
  order_date, 
  amount,
  SUM(amount) OVER (ORDER BY order_date) as running_total
FROM orders;

-- Moving average (last 7 days)
SELECT 
  date,
  revenue,
  AVG(revenue) OVER (ORDER BY date ROWS BETWEEN 6 PRECEDING AND CURRENT ROW) as ma7
FROM daily_revenue;

-- LAG/LEAD — access previous/next row
SELECT 
  date, 
  revenue,
  LAG(revenue, 1) OVER (ORDER BY date) as prev_day_revenue,
  revenue - LAG(revenue, 1) OVER (ORDER BY date) as day_over_day_change
FROM daily_revenue;

Q: PostgreSQL CTEs and recursive queries.

sql
-- CTE (WITH clause) — named subquery
WITH top_customers AS (
  SELECT user_id, SUM(amount) as total
  FROM orders
  WHERE status = 'completed'
  GROUP BY user_id
  ORDER BY total DESC
  LIMIT 100
)
SELECT u.name, tc.total
FROM users u
JOIN top_customers tc ON u.id = tc.user_id;

-- Recursive CTE — tree traversal (org chart, categories)
WITH RECURSIVE org_tree AS (
  -- Base case: top-level manager
  SELECT id, name, manager_id, 0 as depth
  FROM employees
  WHERE manager_id IS NULL
  
  UNION ALL
  
  -- Recursive case: employees who report to current level
  SELECT e.id, e.name, e.manager_id, ot.depth + 1
  FROM employees e
  JOIN org_tree ot ON e.manager_id = ot.id
)
SELECT * FROM org_tree ORDER BY depth, name;

Q: EXPLAIN ANALYZE and query optimisation.

sql
EXPLAIN ANALYZE SELECT * FROM orders WHERE user_id = 123 AND status = 'pending';

-- Output shows:
-- Seq Scan → full table scan (add index)
-- Index Scan → using index (good)
-- Hash Join / Merge Join / Nested Loop → join strategy
-- actual time: real execution time
-- rows: estimated vs actual (large difference = stale statistics → ANALYZE)

-- Optimisation checklist:
-- 1. Identify slow queries: pg_stat_statements
SELECT query, mean_exec_time, calls 
FROM pg_stat_statements ORDER BY mean_exec_time DESC LIMIT 10;

-- 2. Add missing indexes for WHERE/JOIN/ORDER BY columns
-- 3. ANALYZE table to refresh statistics
-- 4. Use connection pooling (PgBouncer)
-- 5. Partition large tables
-- 6. Consider materialized views for expensive aggregations

Revision Notes

PostgreSQL ADVANTAGES:
JSONB, arrays, window functions, CTEs, recursive queries, full-text search
PostGIS (geospatial) | pgvector (AI) | TimescaleDB (time-series)
More standards-compliant than MySQL

MVCC: Readers never block writers. Old row versions kept, cleaned by VACUUM.
AUTOVACUUM: runs automatically. Critical for performance — never disable.

INDEXES:
B-Tree: default, equality+range | Partial: WHERE condition
Expression: computed value | GIN: JSONB, arrays, full-text | BRIN: sequential large tables
pg_trgm: fuzzy/LIKE search

WINDOW FUNCTIONS:
OVER (PARTITION BY ... ORDER BY ...): per-group computation
ROW_NUMBER/RANK/DENSE_RANK: ranking | SUM/AVG OVER: running totals
LAG/LEAD: access previous/next row

RECURSIVE CTE: WITH RECURSIVE → base case UNION ALL recursive case
Use for: tree traversal, org charts, category hierarchies

EXPLAIN ANALYZE: Seq Scan (bad) → Index Scan (good)
pg_stat_statements: identify slow queries | ANALYZE: refresh statistics
PgBouncer: connection pooling
Share:
Join our Community
Daily tips, job alerts, interview help — join engineers learning together
Quick Check — PostgreSQL
1 / 2

What is the most important concept to understand about PostgreSQL for interviews?

Up Next
🔧
PostgreSQLTroubleshooting
Debug common issues with root cause analysis
Also Worth Exploring
← Back to all PostgreSQL modules
ProjectsTroubleshooting