Query Optimisation
7.1 Query Processing Pipeline
Section titled “7.1 Query Processing Pipeline”7.2 Cost-Based Optimisation
Section titled “7.2 Cost-Based Optimisation”The optimiser estimates the cost of alternative execution plans and chooses the cheapest.
Cost model. Cost = I/O cost (disk page accesses) + CPU cost. For disk-bound queries, I/O Dominates.
Catalog statistics: Table cardinality (), attribute value cardinality, number of distinct Values, histogram of value distribution, index information.
Selectivity estimation. For a predicate The selectivity is approximately where is the number of distinct values of in .
| Predicate type | Selectivity estimate |
|---|---|
7.3 Join Algorithms
Section titled “7.3 Join Algorithms”Nested-loop join. For each tuple in Scan all of .
If one relation fits in memory, buffer it and scan the other: cost = .
Block nested-loop join. Use buffer pages. Load blocks of into buffers, scan With the remaining buffer.
Sort-merge join. Sort both relations on the join attribute, then merge.
Efficient for large relations, especially when both are already sorted.
Hash join. Build a hash table on the smaller relation (build phase), then probe with the larger (probe phase).
Best for equi-joins when one relation fits in memory.
Index nested-loop join. For each tuple in Use an index on to find matching tuples.
Efficient if has an index on the join attribute and is small.
7.4 Query Plan Selection
Section titled “7.4 Query Plan Selection”The optimiser explores the space of equivalent logical plans and physical implementations. For Joins, the number of join orderings is (left-deep trees) or (bushy trees). Practical optimisers use dynamic programming with pruning.
Heuristic transformations:
- Push selections down (reduce intermediate result sizes).
- Push projections down (reduce column widths).
- Convert cross products to joins when possible.
- Reorder joins based on estimated cardinalities.
7.5 Key Relationships Between Join Algorithms
Section titled “7.5 Key Relationships Between Join Algorithms”| Algorithm | Best use case | Cost (pages) | Memory required |
|---|---|---|---|
| Nested-loop | Small (outer small) | Minimal | |
| Block nested-loop | Medium-sized tables | pages | |
| Sort-merge | Large tables, sorted input | pages | |
| Hash | Equi-join, one relation fits | Build table | |
| Index nested-loop | Small outer, indexed inner | Minimal |
7.6 Common Pitfalls
Section titled “7.6 Common Pitfalls”- Assuming the cheapest plan for one query is best for all. The optimal join order depends critically on selectivity estimates. Outdated statistics produce poor plans.
- Forgetting that selectivity estimates are just estimates. Uniform distribution assumptions are often wrong. Histograms and sampling improve accuracy but never guarantee correctness.
- Confusing left-deep and bushy trees for the same join. Left-deep trees pipeline well but may miss optimal orderings. Bushy trees can exploit more parallelism.
- Thinking index nested-loop join always beats full table scan. If the outer relation is large and the index has poor selectivity (many matching tuples per key), scanning may be cheaper.
7.7 Worked Examples
Section titled “7.7 Worked Examples”Problem. Consider with 1000 pages and with 500 pages, 100 buffer pages (). Compare the cost of block nested-loop join vs sort-merge join.
Solution. Block nested-loop: pages.
Sort-merge: sorting costs . Sorting : . Merge: . Total: pages.
Block nested-loop is cheaper in this case (6500 vs 7500).
Problem. Estimate selectivity for given , , , .
Solution. For : selectivity . For : selectivity . Assuming independence: combined selectivity (2.5% of rows).
7.8 Applications
Section titled “7.8 Applications”- Big data systems: Query optimisers in Spark SQL, Hive, and Presto use cost-based optimisation adapted for distributed execution, factoring in network transfer costs.
- NoSQL databases: Document stores like MongoDB have query optimisers that select between collection scans and index usage, with query planners showing execution statistics.
- Data warehousing: Columnar databases (Snowflake, Redshift) use optimisers that account for column pruning, vectorised execution, and zone maps for min-max pruning.
- Stream processing: Optimisers for streaming SQL (Flink, Kafka Streams) extend cost models to handle windowed aggregations, state size, and watermark propagation.
7.9 Summary Table of Optimisation Techniques
Section titled “7.9 Summary Table of Optimisation Techniques”| Technique | When to apply | Benefit |
|---|---|---|
| Predicate pushdown | Filter after scan | Reduces rows early |
| Projection pushdown | Wide tables with few columns needed | Reduces I/O per row |
| Join reordering | Multiple joins with selective filters | Minimises intermediate size |
| Index-only scan | Covered query | Avoids table access |
| Materialised view | Expensive aggregations | Precomputes results |