以其创建者Burton Bloom命名的Bloom过滤器是一种低内存数据结构,用于测试集合中的成员资格。
布隆过滤器可以正确指示元素不在集合中的时间,但是可以错误地指示元素在集合中的时间。因此,假阴性是不可能的,但是假阳性是可能的。
9.4.1.1布隆过滤器的用途
布隆过滤器测试一组值以确定它们是否是另一组的成员。
例如,一组为(10,20,30,40),第二组为(10,30,60,70)。布隆过滤器可确定60和70 保证从所述第一组中排除,而10和30是可能的成员。当存储过滤器所需的内存量相对于数据集中的数据量较小时,并且预计大多数数据将无法通过成员资格测试时,Bloom过滤器特别有用。
Oracle数据库使用Bloom筛选器实现各种特定目标,包括:
- 减少在并行查询中传输到从属进程的数据量,尤其是当数据库由于不满足连接条件而丢弃大多数行时
- 在联接中建立分区访问列表时,消除不需要的分区,称为分区修剪
- 测试服务器结果缓存中是否存在数据,从而避免读取磁盘
- 在数据库云服务器单元中过滤成员,尤其是在星型架构中连接大型事实表和小型维度表时
在并行和串行处理中都可能出现布隆过滤器。
9.4.1.2 Bloom过滤器如何工作
布隆过滤器使用位数组来指示包含在集合中。
例如,数组中的8个元素(此示例中使用的任意数字)最初设置为0:
e1 e2 e3 e4 e5 e6 e7 e8
0 0 0 0 0 0 0 0
该数组代表一个集合。为了表示此数组中的输入值i,三个独立的哈希函数(三个是任意的)应用于i,每个函数在1和之间生成一个哈希值8:
f1(i) = h1
f2(i) = h2
f3(i) = h3
例如,要将值存储17在此数组中,哈希函数将i设置为17,然后返回以下哈希值:
f1(17) = 5
f2(17) = 3
f3(17) = 5
在前面的示例中,两个哈希函数碰巧返回相同的值5,称为哈希冲突。因为不同的哈希值是5和3,所以数组中的第5个和第3个元素设置为1:
e1 e2 e3 e4 e5 e6 e7 e8
0 0 1 0 1 0 0 0
测试17集合中的成员资格会逆转该过程。要测试集合是否排除值17,元素3或元素5必须包含0。如果0任一元素中都存在a ,则该集合不能包含17。否定否定是不可能的。
要测试集合是否包含 17,元素3和元素都5必须包含1值。但是,如果测试1对两个元素均指示为a ,则该集合仍可能不包含17。误报是可能的。例如,以下数组可能表示value 22,它1对于element 3和element 也都有一个5:
e1 e2 e3 e4 e5 e6 e7 e8
1 0 1 0 1 0 0 0
9.4.1.3布隆过滤器控件
优化器自动确定是否使用布隆过滤器。
要覆盖优化程序决策,请使用提示 PX_JOIN_FILTER 和 NO_PX_JOIN_FILTER。
也可以看看:
Oracle数据库SQL语言参考,以了解有关Bloom过滤器提示的更多信息
9.4.1.4 Bloom筛选器元数据
V$ 视图包含有关Bloom过滤器的元数据。
您可以查询以下视图:
V$SQL_JOIN_FILTER :此视图显示了由活动Bloom过滤器过滤掉的行数(FILTERED列)和测试的行数(列)PROBED。V$PQ_TQSTAT :此视图显示在执行树的每个阶段通过每个并行执行服务器处理的行数。您可以使用它来监视多少Bloom过滤器减少了并行进程之间的数据传输。
在执行计划中,布隆过滤器是通过关键词指示JOIN FILTER 在Operation列中,前缀:BF在Name列中,如下面的计划片断的第九步骤:
----------------------------------------------------------------------------
| Id | Operation | Name | TQ |IN-OUT| PQ Distrib |
----------------------------------------------------------------------------
...
| 9 | JOIN FILTER CREATE | :BF0000 | Q1,03 | PCWP | |
在Predicate Information计划的部分中,包含以字符串开头的函数的过滤器SYS_OP_BLOOM_FILTER指示使用Bloom过滤器。
9.4.1.5 Bloom过滤器:场景
在此示例中,并行查询将sales事实表连接到products和times维表,并根据会计周进行过滤18。
SELECT /*+ parallel(s) */ p.prod_name, s.quantity_sold
FROM sh.sales s, sh.products p, sh.times t
WHERE s.prod_id = p.prod_id
AND s.time_id = t.time_id
AND t.fiscal_week_number = 18;
查询DBMS_XPLAN.DISPLAY_CURSOR提供以下输出:
SELECT * FROM
TABLE(DBMS_XPLAN.DISPLAY_CURSOR(format => 'BASIC,+PARALLEL,+PREDICATE'));
EXPLAINED SQL STATEMENT:
------------------------
SELECT /*+ parallel(s) */ p.prod_name, s.quantity_sold FROM sh.sales s,
sh.products p, sh.times t WHERE s.prod_id = p.prod_id AND s.time_id =
t.time_id AND t.fiscal_week_number = 18
Plan hash value: 1183628457
----------------------------------------------------------------------------
| Id | Operation | Name | TQ |IN-OUT| PQ Distrib |
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | |
| 1 | PX COORDINATOR | | | | |
| 2 | PX SEND QC (RANDOM) | :TQ10003 | Q1,03 | P->S | QC (RAND) |
|* 3 | HASH JOIN BUFFERED | | Q1,03 | PCWP | |
| 4 | PX RECEIVE | | Q1,03 | PCWP | |
| 5 | PX SEND BROADCAST | :TQ10001 | Q1,01 | S->P | BROADCAST |
| 6 | PX SELECTOR | | Q1,01 | SCWC | |
| 7 | TABLE ACCESS FULL | PRODUCTS | Q1,01 | SCWP | |
|* 8 | HASH JOIN | | Q1,03 | PCWP | |
| 9 | JOIN FILTER CREATE | :BF0000 | Q1,03 | PCWP | |
| 10 | BUFFER SORT | | Q1,03 | PCWC | |
| 11 | PX RECEIVE | | Q1,03 | PCWP | |
| 12 | PX SEND HYBRID HASH| :TQ10000 | | S->P | HYBRID HASH|
|* 13 | TABLE ACCESS FULL | TIMES | | | |
| 14 | PX RECEIVE | | Q1,03 | PCWP | |
| 15 | PX SEND HYBRID HASH | :TQ10002 | Q1,02 | P->P | HYBRID HASH|
| 16 | JOIN FILTER USE | :BF0000 | Q1,02 | PCWP | |
| 17 | PX BLOCK ITERATOR | | Q1,02 | PCWC | |
|* 18 | TABLE ACCESS FULL | SALES | Q1,02 | PCWP | |
----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - access("S"."PROD_ID"="P"."PROD_ID")
8 - access("S"."TIME_ID"="T"."TIME_ID")
13 - filter("T"."FISCAL_WEEK_NUMBER"=18)
18 - access(:Z>=:Z AND :Z<=:Z)
filter(SYS_OP_BLOOM_FILTER(:BF0000,"S"."TIME_ID"))
单个服务器进程扫描times表(步骤13),然后使用混合哈希分发方法将行发送到并行执行服务器(步骤12)。集合中的过程将Q1,03创建布隆过滤器(步骤9)。集合中的进程并行Q1,02扫描sales(步骤18),然后使用Bloom过滤器丢弃行中的行sales(步骤16),然后再Q1,03使用混合哈希分发将它们发送到集合上(步骤15)。集合Q1,03哈希中的进程将这些times行连接到已过滤的sales行(步骤8)。集Q1,01扫描中的进程products(步骤7),然后将行发送到Q1,03(步骤5)。最后,Q1,03加入的过程products 行到上一个哈希联接生成的行(第3步)。
下图说明了基本过程。




