Course contentsShow
← Databases & SQL
Lesson 1055 of 1,9539. MySQL and MariaDB EcosystemsFree lesson

Optimizing Range Scans

Structure data to keep clustered index entries contiguous for range-heavy workloads.

In this lesson, you will learn how to physically structure your data to ensure that range-heavy workloads result in lightning-fast, contiguous disk reads.

The Physical Layout Matters

When we talk about "Optimizing Range Scans," we are focused on the physical storage layer. In MySQL and MariaDB (using the InnoDB engine), the primary key defines the Clustered Index. This means the actual table data is stored in the leaf nodes of the B-Tree, ordered physically by the primary key value.

If your query performs a range scan—such as SELECT * FROM orders WHERE order_date BETWEEN '2023-01-01' AND '2023-01-31'—the database engine needs to traverse the B-Tree to find the start of the range and then scan horizontally across the leaf nodes.

The Power of Contiguity

If your data is fragmented, the engine has to perform expensive "random I/O" jumps to fetch records. However, if your data is physically contiguous, the engine performs "sequential I/O." Sequential reads are significantly faster because modern storage systems (and OS read-ahead caches) can predict the next block of data before the database even requests it.

To optimize this, you must structure your clustered index to match your most frequent range scans.

Illustrative Example

Imagine a logs table. If you frequently query by time, but your primary key is a random UUID, your logs are scattered across the disk in the order they were generated, regardless of time. A range scan for "today's logs" will result in fragmented disk access.

If you instead use a composite primary key that leads with a timestamp (or a naturally increasing ID), the data is stored in chronological order:

CREATE TABLE logs (
    log_date DATE NOT NULL,
    log_id INT NOT NULL,
    message TEXT,
    PRIMARY KEY (log_date, log_id)
);

By placing log_date first, all logs for a specific day are physically adjacent. When you run your range scan, the engine performs a single seek to the start of the date range and then sweeps across the leaf nodes, reading data blocks sequentially until the end of the range. This minimizes disk head movement and maximizes the throughput of your cache.

Key Takeaway: To optimize range scans, design your clustered index so that the most frequently queried range column is the leading part of the primary key, ensuring the data is physically stored in the sequence you need to read it.