SQL Practice Logo

SQLPractice Online

ROW_NUMBER, RANK, DENSE_RANK: Performance

Module: Window Functions

**Indexing Strategy:**

```sql

-- For PARTITION BY department ORDER BY salary DESC

CREATE INDEX idx_emp_dept_salary ON employees(department, salary DESC);

-- For ORDER BY hire_date, employee_id

CREATE INDEX idx_emp_hire_id ON employees(hire_date, employee_id);

```

**Performance Benchmarks (1M row table):**

| Scenario | No Index | With Index | Improvement |

|----------|----------|------------|-------------|

| ROW_NUMBER() simple | 3.2s | 0.8s | 75% faster |

| RANK() with PARTITION BY | 8.5s | 1.2s | 86% faster |

| DENSE_RANK() complex | 12.1s | 2.1s | 83% faster |

**Memory Usage:**

- **ROW_NUMBER()**: Minimal memory (just a counter)

- **RANK()**: Low memory (tracks tie groups)

- **DENSE_RANK()**: Medium memory (maintains dense sequence)

**Optimization Tips:**

1. **Index ORDER BY columns** - Massive performance gain

2. **Index PARTITION BY columns** - Enables efficient grouping

3. **Use ROW_NUMBER when possible** - Fastest of the three

4. **Filter before ranking** - Use WHERE to reduce dataset size

5. **Avoid unnecessary columns** - Select only what you need

**Query Execution Order:**

1. FROM clause (table scan)

2. WHERE clause (filtering)

3. Window functions (ranking)

4. SELECT clause (projection)

5. ORDER BY clause (final sorting)

**Best Practices:**

- **Always include tie-breakers** in ORDER BY for consistent results

- **Use meaningful column names** for rank columns (position, tier, rank)

- **Consider QUALIFY clause** (PostgreSQL) for direct rank filtering

- **Test with realistic data volumes** - Performance varies with data size

- **Monitor query plans** - Ensure indexes are being used

**Anti-Patterns to Avoid:**

❌ **Don't do this:**

```sql

-- No tie-breaker, inconsistent results

SELECT *, ROW_NUMBER() OVER(ORDER BY salary) FROM employees;