Definition · Point lookup and range queryA point lookup retrieves the row for one exact key. A range query retrieves every row whose key lies between two bounds, and is priced by the number of rows k it returns.
An index is ordered if it stores keys in a comparison order, and unordered if it stores them by a hash of the key. Only an ordered index has an access path for a range.
The hash index's 1 is worth taking seriously rather than waving at. Under simple uniform hashing the expected number of probes is Θ(1 + α) in the load factor α, so a table kept at a sensible load factor really does answer in about one access — and the worst case, where every key collides, really is Θ(n). Those are Algorithms' results, proved in “Hashing with Chaining”; what this lesson adds is that on disk the unit is a page read and the constant is therefore expensive.
10⁶ rows B = 500 200 rows a page ranges return 100 rows
hash point 1 I/O
range 10⁶ / 200 = 5 000 I/O (full scan)
tree height 500² = 250 000 < 10⁶ ≤ 125 000 000 = 500³ → h = 3
point 3 I/O
range (3 − 1) + ⌈100/200⌉ = 3 I/O
mix 900 point/s + 100 range/s
hash 900(1) + 100(5 000) = 500 900 I/O a second
tree 900(3) + 100(3) = 3 000 I/O a second
The hash index does one hundred and sixty-seven times the I/O of the tree on that mix, and it is genuinely three times cheaper on the operation it is good at. Both facts come out of the same four numbers. Which one you quote is a choice about what you want the answer to be.
Where the ordering reverses
Set the two totals equal and solve for the range rate r at a fixed point rate. With 900 point lookups a second: 900(1) + r(5 000) = 900(3) + r(3), so r(5 000 − 3) = 900(3 − 1) and r = 1800/4997 ≈ 0.360 range scans a second. One range query every three seconds is enough to make the tree the cheaper engine on this table.
Example · A workload where the hash genuinely winsRemove the ranges entirely. At 900 point lookups a second and nothing else, the hash index does 900 I/O a second and the tree does 2 700 — three times as many, exactly the ratio of 1 to h. The true claim behind “hash is faster” is alive; it is just very small, and it is a claim about one operation.
The same misconception exists in memory, where “a hash table is always the fastest map” is corrected by pointing out that it cannot answer predecessor, range or ordered iteration at all. “Choosing a Structure” on the Algorithms path is that statement. This lesson is the same fact with a disk attached, and the disk is what turns a structural limitation into a number: not “unsupported” but 5 000 I/O.
What the count assumes: that pages hold their nominal number of rows, that nothing is cached, and that the range is contiguous in the index's key order. Cache the tree's top two levels and its point lookup falls from 3 to 1, at which point the hash index's advantage on the operation it is good at disappears entirely — which is worth knowing before anyone builds an argument on the 1 against 3.