Analyzequery
Home Cost-Based Optimization Models Index Selection Mechanics: A Comparative Study of B-Tree and Bitmap Costing
Cost-Based Optimization Models

Index Selection Mechanics: A Comparative Study of B-Tree and Bitmap Costing

By Aris Varma Dec 14, 2025
Index Selection Mechanics: A Comparative Study of B-Tree and Bitmap Costing
All rights reserved to analyzequery.com

Relational query optimization mechanics serve as the foundational framework for modern database performance. At the heart of this discipline lies the Cost-Based Optimizer (CBO), an algorithmic component tasked with determining the most efficient execution plan for SQL statements by evaluating the cumulative costs of data retrieval. These costs are primarily measured through I/O operations and CPU cycle utilization, with the ultimate goal of minimizing the total time required to return a result set.

Database engines like MySQL and PostgreSQL employ sophisticated mathematical models to weigh the benefits of various access paths. The choice between an Index-Only Scan, a Bitmap Heap Scan, or a Sequential Scan is rarely static; it depends heavily on data distribution statistics, the physical storage layout of the data, and the hardware-specific cost constants defined within the database configuration. In high-concurrency environments, even a minor miscalculation by the statistical estimator can lead to significant performance degradation.

By the numbers

  • 0.01 to 0.05:The typical default range forCpu_tuple_costIn PostgreSQL, representing the estimated CPU effort to process a single row.
  • 1.0:The standardized cost value for a sequential page read in most CBO models, used as a baseline for other I/O operations.
  • 4.0:The traditional defaultRandom_page_costIn PostgreSQL, highlighting the significantly higher expense of non-sequential disk access.
  • 5%–15%:The approximate selectivity threshold beyond which many optimizers flip from an index scan to a full table scan to avoid the overhead of random I/O.
  • 8 KB:The standard page size in PostgreSQL, which acts as the atomic unit of measurement for I/O costing calculations.
  • 16 KB:The default page size for MySQL’s InnoDB storage engine, influencing how many index entries fit within a single leaf node.

Background

The origins of relational query optimization can be traced back to the landmark 1979 paper by Patricia Selinger and her colleagues at IBM Research, titled ‘Access Path Selection in a Relational Database Management System.’ This research introduced the first detailed framework for cost-based optimization, establishing the methodology of using statistics and cardinality estimates to select join orders and access methods. Before the Selinger model, database systems often relied on rule-based optimizers (RBOs), which applied rigid, heuristic-driven transformations regardless of the actual data volume or distribution.

As relational databases transitioned from simple storage systems to complex platforms handling petabytes of data, the Selinger model evolved. Modern systems now incorporate sophisticated algorithms for handling histograms, most common values (MCV) lists, and hyperloglog sketches to provide the CBO with a more granular view of the data. This evolution was necessary to address the ‘black box’ nature of query execution, where small changes in a WHERE clause could lead to vastly different execution times. Today, the mechanics of index selection represent a high-stakes balance between the low-latency promise of B-Trees and the bulk-processing efficiency of sequential and bitmap-assisted operations.

B-Tree Indexing and the Index-Only Scan

The B-Tree (Balanced Tree) remains the most prevalent indexing structure in relational systems. Its primary advantage is its ability to maintain sorted data, allowing for logarithmic search complexity (O(log n)). When an optimizer considers an Index-Only Scan, it is evaluating whether all the columns requested in the SELECT and WHERE clauses exist within the index itself. If so, the database engine can avoid the ‘heap fetch’ phase, where it would otherwise need to retrieve the actual table rows from the disk.

The costing for an Index-Only Scan is typically calculated as a function of the height of the B-Tree and the number of leaf pages that must be traversed. Because the index is significantly smaller than the base table, it often resides entirely in the database buffer cache, reducing physical I/O to nearly zero. However, in PostgreSQL, the Index-Only Scan is contingent on the ‘visibility map.’ If many rows have been recently updated or deleted and not yet processed by the VACUUM command, the optimizer may conclude that a heap check is necessary to verify row visibility, thereby increasing the cost and potentially disqualifying the Index-Only Scan.

Bitmap Heap Scans in PostgreSQL

PostgreSQL employs a unique mechanism known as the Bitmap Heap Scan to bridge the gap between highly selective index lookups and broad sequential scans. This process occurs in two distinct phases. First, theBitmap Index ScanTraverses the index and creates a bitmap in memory, where each bit corresponds to a physical page in the table. If a row matches the query predicate, its corresponding bit is set to 1.

Second, theBitmap Heap ScanReads the bitmap and visits only the table pages marked with a 1. This method is mathematically advantageous when the query is moderately selective. By sorting the bits by physical disk location before the heap fetch, PostgreSQL transforms what would have been many disparate random I/O requests into a series of more efficient, semi-sequential I/O requests. The CBO calculates the cost of this operation by estimating the memory required for the bitmap (to avoid ‘lossy’ bitmaps that store page-level rather than row-level references) and the reduced I/O cost of the sorted access pattern.

MySQL InnoDB: Clustered Index Mechanics

MySQL’s InnoDB engine approaches index selection differently due to its use of clustered indexes. In InnoDB, the primary key is the table. Every secondary index entry contains a copy of the primary key columns. This architecture makes Index-Only Scans highly efficient for queries that only involve the secondary index and the primary key. However, if a query requires columns not present in the secondary index, a ‘bookmark lookup’ occurs, requiring a second traversal of the primary B-Tree.

The MySQL CBO uses ‘Index Dive’ mechanics to estimate the number of rows within a range. It literally descends the B-Tree to count the number of entries in a specific branch. While this provides high accuracy, it introduces overhead for queries with many IN() clauses. The optimizer compares this ‘dive’ cost against the cost of a full table scan. In InnoDB, a full table scan is essentially a sequential read of the clustered index, which is often faster than performing thousands of non-sequential lookups via a secondary index for high-cardinality data.

Comparative Costing Models

The following table illustrates how PostgreSQL and MySQL CBOs differ in their primary costing priorities during execution plan generation:

FeaturePostgreSQL (CBO)MySQL InnoDB (CBO)
Primary Scan TypeHeap Scan (Sequential)Clustered Index Scan
Intermediate StructureBitmap Index/Heap ScanMRR (Multi-Range Read)
Costing UnitArbitrary units (seq_page_cost)Engine-specific cost units
Index-Only EligibilityVisibility Map dependentSecondary Index coverage dependent
Random I/O WeightConfigurable (random_page_cost)Hardcoded/Weighted heuristics

In PostgreSQL, theRandom_page_costSetting is the primary lever for tuning index selection. If set too high, the optimizer will favor sequential scans even when an index would be faster. Conversely, MySQL relies heavily on theOptimizer_switchSettings, such asMrr(Multi-Range Read), which attempts to emulate PostgreSQL’s bitmap-like behavior by buffering and sorting primary key lookups from secondary indexes to minimize disk head movement.

Data Distribution and the Tipping Point

A critical aspect of relational query optimization mechanics is identifying the ‘tipping point’ where an index lookup becomes more expensive than a sequential scan. This is frequently observed in high-cardinality scenarios where a column has many unique values, but a specific query still matches a large percentage of the total rows. For example, in a table with 10 million rows, a query matching 1 million rows (10% selectivity) would require 1 million random I/O operations if using a standard B-Tree index scan.

Because random I/O is physically slower than sequential I/O (due to disk seek latency or SSD controller overhead), the CBO will calculate that reading the entire 10-million-row table sequentially is actually faster. This is because sequential reads benefit from hardware prefetching and OS-level read-ahead buffers. The accuracy of this decision rests entirely on theStatistical estimator. If the statistics are stale, the estimator might think it is only retrieving 10,000 rows when it is actually retrieving 1 million, leading to a disastrously slow execution plan.

Advanced Optimization Heuristics

Beyond simple I/O and CPU costing, modern optimizers use advanced heuristics to prune the search space of possible execution plans.Predicate pushdownIs a foundational technique where filters are applied as early as possible in the execution pipeline to reduce the size of intermediate result sets. This is particularly vital in complex JOIN operations, where reducing the inner or outer table size early can prevent a nested loop join from spiraling into billions of iterations.

Furthermore,View mergingAndSubquery flatteningAllow the optimizer to see ‘through’ complex SQL abstractions, treating the entire query as a single unit for indexing purposes. In these scenarios, the optimizer evaluates whether it can use an index on a base table to satisfy a condition defined several layers deep in a CTE (Common Table Expression). The cascading application of these rules, derived from decades of advancements since the Selinger era, ensures that the database engine can handle the trade-offs between different indexing structures and retrieval strategies effectively.

Future Directions in Costing

The discipline is currently shifting towardMachine Learning-based cardinality estimation. Traditional histograms struggle with correlated columns (e.g., a ‘City’ column and a ‘Zip Code’ column). While a standard CBO might assume independence and multiply the selectivities, leading to an underestimation of the result set, neural-network-backed estimators can learn these correlations from the data itself. This represents the next frontier in query optimization, where the costing models are no longer static formulas but dynamic, learned patterns that adapt to the specific nuances of a dataset’s distribution.

#Relational query optimization# cost-based optimizer# B-Tree index# Bitmap heap scan# MySQL InnoDB# PostgreSQL# SQL execution plans# database indexing
Aris Varma

Aris Varma

Aris is a Contributor focused on the accuracy of statistical estimators and their impact on query graph analysis. He frequently audits how different database engines handle complex subqueries and the resulting execution plan variances.

View all articles →

Related Articles

Cloud-Native Architectures Redefining Query Execution Plans Statistics and Cardinality Estimation All rights reserved to analyzequery.com

Cloud-Native Architectures Redefining Query Execution Plans

Elias Thorne - Apr 21, 2026
The Advancing Frontier of AI-Enhanced Query Optimizers Statistics and Cardinality Estimation All rights reserved to analyzequery.com

The Advancing Frontier of AI-Enhanced Query Optimizers

Elias Thorne - Apr 21, 2026
The Mechanics of SQL Performance: Refining Join Ordering and Statistical Accuracy Execution Plan Analysis and Visualization All rights reserved to analyzequery.com

The Mechanics of SQL Performance: Refining Join Ordering and Statistical Accuracy

Elias Thorne - Apr 20, 2026
Analyzequery