How does Exadata implement storage index filtering?
If the Exadata Storage Grid is the muscle of the system, Storage Indexing is the "eyes." It allows Exadata to see what data is not worth reading, saving a massive amount of I/O before a single block is even touched.
Unlike a traditional B-Tree index that helps you find a needle in a haystack, a Storage Index is an "Anti-Index"—it helps you realize the needle isn't in this specific pile of hay, so you can skip it entirely.
Storage Indexes are memory-resident structures located on the storage cells.
The grid divides all data on a disk into 1MB storage regions.
Minimum and Maximum values for up to 24 columns (per table).
Null Value bitmask: A flag indicating if the region contains any nulls.
Set Membership (Bloom Filters): For columns with low cardinality (fewer than 200 distinct values), it creates a compact "dictionary" of exactly what is inside.
When a Database Server sends a Smart Scan request to the storage cell, it includes the WHERE clause (predicates). The storage cell software (CELLSRV) then performs the following logic:
Check the Index: Before reading the 1MB region from disk or flash, it compares the query predicate to the stored Min/Max values.
The Decision: * If the query is WHERE price > 100 and the region’s MAX is 90, the cell skips the region entirely.
If the query value falls inside the Min/Max range, the cell must read the region to find the specific rows.
Result: This is called I/O Pruning.
One of the most advanced uses of Storage Indexing is Bloom Filter Offloading.
When you join a small "Dimension" table to a massive "Fact" table, the database creates a Bloom Filter (a compact probabilistic map) of the join keys. This filter is sent to the storage cells. The Storage Index uses this filter to skip regions of the Fact table that definitely don't have a matching key in the Dimension table.
Pro Tip: This allows "Join Filtering" to happen at the storage layer, often before the data even leaves the disk.
The best part about Storage Indexes is that you don't have to manage them. There is no CREATE STORAGE INDEX command.
Automatic Creation: Exadata monitors your queries.
Automatic Maintenance: As data is written or updated, the storage cell updates the Min/Max values in real-time.
Persistency (Newer Generations): Starting with Exadata System Software 21.2, these indexes can be persisted to local SSDs so they don't have to be "re-learned" after a cell restart.
You can see exactly how much work the Storage Index is doing for your session by querying v$sesstat:
SELECT name, value/1024/1024 as MB
FROM v$statname n, v$sesstat s
WHERE n.statistic# = s.statistic#
AND n.name = 'cell physical IO bytes saved by storage index'
AND s.sid = sys_context('USERENV', 'SID');
| Feature | Traditional B-Tree Index | Exadata Storage Index |
| Storage | Persistent on disk (takes space). | Memory-resident (zero disk footprint). |
| Creation | Manual (CREATE INDEX). | Automatic (based on usage). |
| Goal | Find the exact location of a row. | Skip large regions that don't match. |
| Best For | Single-row lookups (OLTP). | Large table scans (Analytics/DW). |