You are on page 1of 18

Bloom Filters in Oracle Databases

Presented by
Joel Goodman
Oracle University EMEA
About Me

Email: Joel.Goodman@oracle.com
Blog: dbatrain.wordpress.com
Global Technical Lead Database Certifications
Global DBA Curriculum Quality Review Team
OCP DBA 7.3 to 12c
OCM DBA 9i to 12c
Member of Oak Table
Oracle University 1997 to Present
Oracle Support 1994 to 1996
Mini-Lesson Outline

When and Why are Bloom Filters Used


The Join Problem Solved by Bloom Filters
The Details of Bloom Filters
Bloom Filters in Parallel Execution
Bloom Filter Partiton Pruning
Exadata Smart Joins with Bloom Filters
In Memory Column Store with Bloom Filters
When and Why Are Bloom Filters Used
Parallel Join Queries
To reduce Slave to Slave communication overheads
Optimiser decides to use based on join selectivity and size
PX_JOIN_FILTER and NO_PX_JOIN_FILTER hints are available.
Joins using In Memory Column Store
Smart Joins in Exadata
To reduce results returned from cells on second table
Join Filter Partition Pruning
To prune partitions that have no matching keys
To Support Result Cache
Not documented how Oracle Uses This
The Join Problem Solved by Bloom Filters
Joining Data involves
Accessing one row source and applying non-join filters if any
Accessing a second row source and applying non-join filters if any
Possibly distributing one set of rows to be joined to the second set.
Through Memory when performing Parallel Query
Across the interconnect if multiple instances are involved
Distributed rows that fail to join result in wasteful use of
instructions and possibly bandwidth over the Interconnect.
Bloom Filters can significantly reduce this resource wastage.
The Details of Bloom Filters
Bloom filters have been used to optimize parallel joins since Oracle
10g
A Bloom filter is a data structure that can be used to test if an
element is a member of a set.
Bloom filter properties for Joins:
A set of Hash algorithms and a bitmap are used to create a composite
signature of all keys in one set
The bitmap is sent to be processed by the join
The same hash algorithms are used against the second set of keys to
probe the bitmap
The time required to check whether an element is a member of the set is
constant.
The overhead of sending the bloom filter to be used in the join is less
than the overhead saved by eliminating rows that can never possibly
join
False positives are possible but false negatives are not
The Details of Bloom Filters
Bloom filters use N hash algorithms and a bit array
Bloom Filter creation acts on the first set of keys
Each hash algorithm takes input:
Length of the bit array
Value of each key
Each hash algorithm produces output as follows:
Offset into the bit array for each key
The bit at that offset is set to 1
Bloom Filter use acts on the second set of keys
Each key in the second set is hashed by each algorithm
The bit signature is compared to the bits in the array
Three possible results
Negatives the corresponding rows are not distributed
False positives the corresponding rows are not joined
True Positives the corresponding rows are joined
Parallel Join Operations and Bloom Filters
To reduce overheads of data communication between PX sets during
parallel joins, Oracle can create and use a memory structure called a
bloom filter.
Used to quickly probe the existence of rows between different row sets
Used during PX-set-to-PX-set distribution via TQs when PX servers in same
instance
Used during PX-set-to-PX-set distribution via TQs and interconnect when
using RAC and PX servers to distribute across interconnect
Used during PX-set-to-PX-set distribution via TQs using an Exadata
Database machine to enable cells to reduce the data sent over the storage
network
Are created in the Database Server and used in Exadata Cells.
Parallel Join with Bloom Filter
select * from t1,t2 where t1.id=t2.id and t1.mod=42;
------------------------------------------------------------------
|Id Operation |Name |Rows | TQ |IN-OUT|
-------------------------------------------------------------------
| 0|SELECT STATEMENT | |3812G| | |
| 1| PX COORDINATOR | | | | |
| 2| PX SEND QC (RANDOM) |:TQ10002|3812G|Q1,02| P->S |
|* 3| HASH JOIN BUFFERED | |3812G|Q1,02| PCWP |
| 4| JOIN FILTER CREATE |:BF0000 |6182M|Q1,02| PCWP |
| 5| PX RECEIVE | |6182M|Q1,02| PCWP |
| 6| PX SEND HASH |:TQ10000|6182M|Q1,00| P->P |
| 7| PX BLOCK ITERATOR | |6182M|Q1,00| PCWC |
|* 8| TABLE ACCESS STORAGE FULL|T1 |6182M|Q1,00| PCWP |
| 9| PX RECEIVE | | 13G|Q1,02| PCWP |
| 10| PX SEND HASH |:TQ10001| 13G|Q1,01| P->P |
| 11| JOIN FILTER USE |:BF0000 | 13G|Q1,01| PCWP |
| 12| PX BLOCK ITERATOR | | 13G|Q1,01| PCWC |
|*13| TABLE ACCESS STORAGE FULL|T2 | 13G|Q1,01| PCWP |
-------------------------------------------------------------------
V$SQL_JOIN_FILTER

SYS@orcl_2 SQL> desc v$SQL_JOIN_FILTER


Name Null? Type
----------------------------------------- -------- ----------------------------
QC_SESSION_ID NUMBER
QC_INSTANCE_ID NUMBER
SQL_PLAN_HASH_VALUE NUMBER
FILTER_ID NUMBER
LENGTH NUMBER
BITS_SET NUMBER
FILTERED NUMBER
PROBED NUMBER
ACTIVE NUMBER
CON_ID NUMBER

SYS@orcl_2 SQL> SELECT FILTERED, PROBED, PROBED-FILTERED AS USED


FROM V$SQL_JOIN_FILTER
WHERE QC_SESSION_ID = SYS_CONTECT(userenv,sid);

FILETERD PROBED USED


-------- ------ ----
190325 225000 34675
Partition Pruning and Bloom Filters

To reduce overheads of Partition Pruning on join conditions Join-Filter


pruning is done. This has been available since Oracle 11g Release 1.
The first table has all partitions scanned
The join key data returned is analyzed
A Bloom Filter is created based on the keys returned
Pruning of the second table can be done based on the bloom filter in
addition to any pruning from other filter columns
Join Filter Partition Pruning
SQL> SELECT * from table1, table2 where t1.cola = t2.cola and t1.colb = 999;

--------------------------------------------------------------------------
| Id | Operation | Name | Pstart | Pstop |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | |
| *1 | HASH JOIN | | | |
| 2 | PART JOIN FILTER CREATE | :BF0000 | | |
| 3 | PARTITION HASH ALL | | 1| 16 |
| *4 | TABLE ACCESS FULL | TABLE1 | 1| 16 |
| 5 | PARTITION HASH JOIN-FILTER | |:BF0000 | :BF0000|
| 6 | TABLE ACCESSS FULL | TABLE2 | BF0000 | :BF0000|
-------------------------------------------------------------------------

Predicate Information (identified by operation id):


---------------------------------------------------

1 - access(TABLE1".COLA"=TABLE2"."COLA")
filter(TABLE1"."COLB=999)
Smart Scan Join Processing with Bloom Filters
A Smart Scan is performed on the driving table used in the join
Each cell returns its portion of the table after filtering rows in the
cell
The Bloom Filter is built in the database instance and sent together
with the query to access the second table.
A Smart Scan is performed on the driven table and then the Bloom
Filter is applied in the cells
Only True and False Positives are returned by the cells for the
Smart Scan of the second table
The False Positives are eliminated during the join perfomed in the
database instance.
Smart Scan Join Filtering
SQL> SELECT AVG(s.amount_sold) FROM customers cu, sales s
2 WHERE cu.cust_id = s.cust_id
3 AND cu.cust_credit_limit > 5000;

-----------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | TQ |IN-OUT| PQ Distrib |
-----------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 19 | 55979 (1)| 00:11:12 | | | |
| 1 | SORT AGGREGATE | | 1 | 19 | | | | | |
| 2 | PX COORDINATOR | | | | | | | | |
| 3 | PX SEND QC (RANDOM) | :TQ10002 | 1 | 19 | | | Q1,02 | P->S | QC (RAND) |
| 4 | SORT AGGREGATE | | 1 | 19 | | | Q1,02 | PCWP | |
|* 5 | HASH JOIN | | 577M| 10g| 55979 (1)| 00:11:12 | Q1,02 | PCWP | |
| 6 | JOIN FILTER CREATE | :BF0000 | 57M| 547M| 14499 (1)| 00:02:54 | Q1,02 | PCWP | |
| 7 | PX RECEIVE | | 57M| 547M| 14499 (1)| 00:02:54 | Q1,02 | PCWP | |
| 8 | PX SEND HASH | :TQ10000 | 57M| 547M| 14499 (1)| 00:02:54 | Q1,00 | P->P | HASH |
| 9 | PX BLOCK ITERATOR | | 57M| 547M| 14499 (1)| 00:02:54 | Q1,00 | PCWC | |
|* 10 | TABLE ACCESS STORAGE FULL| CUSTOMERS | 57M| 547M| 14499 (1)| 00:02:54 | Q1,00 | PCWP | |
| 11 | PX RECEIVE | | 774M| 6651M| 24044 (1)| 00:04:49 | Q1,02 | PCWP | |
| 12 | PX SEND HASH | :TQ10001 | 774M| 6651M| 24044 (1)| 00:04:49 | Q1,01 | P->P | HASH |
| 13 | JOIN FILTER USE | :BF0000 | 774M| 6651M| 24044 (1)| 00:04:49 | Q1,01 | PCWP | |
| 14 | PX BLOCK ITERATOR | | 774M| 6651M| 24044 (1)| 00:04:49 | Q1,01 | PCWC | |
|* 15 | TABLE ACCESS STORAGE FULL| SALES | 774M| 6651M| 24044 (1)| 00:04:49 | Q1,01 | PCWP | |
-----------------------------------------------------------------------------------------------------------------------------
Smart Scan Join Filtering

Predicate Information (identified by operation id):


---------------------------------------------------

5 - access("CU"."CUST_ID"="S"."CUST_ID")
10 - storage("CU"."CUST_CREDIT_LIMIT">5000)
filter("CU"."CUST_CREDIT_LIMIT">5000)
15 - storage(SYS_OP_BLOOM_FILTER(:BF0000,"S"."CUST_ID"))
filter(SYS_OP_BLOOM_FILTER(:BF0000,"S"."CUST_ID"))
In Memory Join Processing with Bloom Filters
A Scan is performed on the driving table used in the join
The Bloom Filter is built in the database instance and sent together
with the query to access the second table.
A Scan is performed on the driven table and then the Bloom Filter is
applied
Only True and False Positives are returned for the Scan of the
second table
The False Positives are eliminated during the join
In Memory Join Filtering

SQL> SELECT AVG(s.amount_sold) FROM customers cu, sales s


2 WHERE cu.cust_id = s.cust_id
3 AND cu.cust_credit_limit > 5000;

--------------------------------------------------------------------------------------------------
| Id | Operation | Name Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | 1 | 19 | 55979 (1)| 00:11:12 |
| 1 | SORT AGGREGATE | | 1 | 19 | | |
|* 2 | HASH JOIN | | 577M| 10g| 55979 (1)| 00:00:02 |
| 3 | JOIN FILTER CREATE | :BF0000 | 57M| 547M| 14499 (1)| 00:00:02 |
|* 4 | TABLE ACCESS INMEMORY FULL | CUSTOMERS | 57M| 547M| 14499 (1)| 00:00:02 |
| 5 | JOIN FILTER USE |:BF0000 | 774M| 6651M| 24044 (1)| 00:00:02 |
|* 6 | TABLE ACCESS INMEMORY FULL | SALES | 774M| 6651M| 24044 (1)| 00:00:02 |
--------------------------------------------------------------------------------------------------
In MemoryJoin Filtering

Predicate Information (identified by operation id):


---------------------------------------------------

2 - access("CU"."CUST_ID"="S"."CUST_ID")
4- storage("CU"."CUST_CREDIT_LIMIT">5000)
filter("CU"."CUST_CREDIT_LIMIT">5000)
6 - storage(SYS_OP_BLOOM_FILTER(:BF0000,"S"."CUST_ID"))
filter(SYS_OP_BLOOM_FILTER(:BF0000,"S"."CUST_ID"))

You might also like