SQL Practice Logo

SQLPractice Online

Understanding EXPLAIN Plans: Performance

Module: Query Optimization & Performance

**Critical Red Flags in Execution Plans:**

1. **Sequential/Table Scans on Large Tables**

- Indicator: "Seq Scan" (PostgreSQL), "type: ALL" (MySQL), "Table Scan" (SQL Server)

- Impact: O(n) performance, reads entire table

- When acceptable: Small tables (<1000 rows), retrieving >20% of rows

- Fix: Add appropriate index on WHERE/JOIN columns

2. **High Row Count Discrepancies**

- Indicator: Estimated rows: 100, Actual rows: 100,000

- Impact: Optimizer chooses wrong join method or order

- Cause: Outdated statistics, data skew

- Fix: Run ANALYZE (PostgreSQL), ANALYZE TABLE (MySQL), UPDATE STATISTICS (SQL Server)

3. **Nested Loop Joins on Large Tables**

- Indicator: "Nested Loop" with high row counts

- Impact: O(n × m) performance, exponential slowdown

- When acceptable: Small outer table (<1000 rows), indexed inner table

- Fix: Add index on join column or force hash join

4. **Expensive Sort Operations**

- Indicator: "Sort" with high cost, "Using filesort" (MySQL)

- Impact: O(n log n) CPU and memory usage

- When acceptable: Small result sets, necessary ORDER BY

- Fix: Add index on ORDER BY columns, reduce result set size

5. **Temporary Tables and Filesorts**

- Indicator: "Using temporary" (MySQL), "Materialize" (PostgreSQL)

- Impact: Extra I/O, memory usage, slower execution

- Cause: Complex GROUP BY, DISTINCT, or subqueries

- Fix: Simplify query, add indexes, increase memory

6. **Hash Operations Spilling to Disk**

- Indicator: "Hash Batches" > 1, "Disk" in buffers

- Impact: Massive slowdown (100x+), disk I/O

- Cause: Insufficient memory for hash table

- Fix: Increase work_mem (PostgreSQL), join_buffer_size (MySQL)

7. **Multiple Scans of Same Table**

- Indicator: Same table appears multiple times in plan

- Impact: Redundant I/O and processing

- Cause: Correlated subqueries, poor query structure

- Fix: Rewrite with CTEs or JOINs

**Performance Benchmarks:**

- **Index Seek**: 0.01-0.1ms per lookup

- **Index Scan**: 1-10ms per 1000 rows

- **Table Scan**: 10-100ms per 1000 rows