What Is a Bloom Filter in Oracle Database?

When working with big databases, speed matters. Oracle uses many smart tricks to make things faster. One of these tricks is called the Bloom filter. In this post, I’ll explain what it is and how it helps Oracle database run queries faster — in simple terms!

The Problem: Big Tables and Slow Joins

Let’s say we have two tables:

  • One big table: SALES (millions of rows)
  • One small table: CUSTOMERS (a few thousand rows)

And you run this query:

SELECT s.*, c.country 
FROM sales s JOIN customers c 
ON s.customer_id = c.customer_id
WHERE c.country = 'Switzerland';

The Optimizer needs to:

  1. Read the CUSTOMERS table
  2. Join it with SALES
  3. Filter for country = 'Switzerland'

This join can be expensive if SALES is huge.

But joining big tables can be slow.

How Bloom Filters Help

The Bloom filter is like a super-fast “maybe list.”

It helps Oracle quickly skip rows in SALES that won’t match with CUSTOMERS.

Here’s how:

  • Oracle first reads CUSTOMERS and creates a Bloom filter using the customer_id values.
  • Then, as Oracle scans SALES, it checks each customer_id using the Bloom filter.
  • If there’s no chance of a match, Oracle skips the row — no join needed!

This can greatly reduce the amount of data Oracle has to process.

Let’s look at a query that might trigger a Bloom filter:

SELECT /*+ USE_HASH(c s) FULL(s) FULL(c) PARALLEL(s 4) PARALLEL(c 4) */
       s.sale_id, s.amount, c.country
FROM   customers c
JOIN   sales s
ON     c.customer_id = s.customer_id
WHERE  c.country = 'Germany';
Explanation of the hint:
  • USE_HASH: use a hash join (Bloom filters are only used with hash joins)
  • FULL: use full table scans
  • PARALLEL: run in parallel (Bloom filters are mostly used in parallel execution)
------------------------------------------------------------------------------------------------
| Id  | Operation                      | Name      | Rows  | Bytes | Cost |                  |
------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT               |           |       |       |      |                    |
|   1 |  PX COORDINATOR                |           |       |       |      |                    |
|   2 |   PX SEND QC (RANDOM)          | :TQ10001  |       |       |      |                    |
|   3 |    HASH JOIN                   |           |       |       |      |                    |
|   4 |     PX RECEIVE                 |           |       |       |      |                    |
|   5 |      PX SEND BROADCAST         | :TQ10000  |       |       |      |                    |
|   6 |       TABLE ACCESS FULL        | CUSTOMERS |       |       |      |                    |
|   7 |     PX BLOCK ITERATOR          |           |       |       |      |                    |
|   8 |      TABLE ACCESS FULL         | SALES     |       |       |      |                    |
------------------------------------------------------------------------------------------------
Predicate Information:
----------------------
- bloom filter predicate on SALES.CUSTOMER_ID

Look for “bloom filter predicate” or:

  • BLOOM FILTER CREATE
  • BLOOM FILTER USE

You don’t need to turn on Bloom filters — Oracle does it when it’s helpful.

Use hash joins + parallel to make it more likely Oracle will apply them.

Always check your execution plan to see what’s happening behind the scenes.

Published by dbaliw

Highly experienced Oracle Database Administrator and Exadata Specialist with over 15 years of expertise in managing complex database environments. Skilled in cloud technologies, DevOps practices, and automation. Certified Oracle Cloud Infrastructure Architect and Oracle Certified Master with a strong background in performance tuning, high availability solutions, and database migrations.

Leave a comment