Bloom Filter在Oracle 19c中对JOIN有效,因其仅在HASH JOIN场景下、驱动表数据量适中且探测表足够大时被优化器启用,核心是将JOIN时的过滤提前下推至扫描阶段,通过V$SQL_JOIN_FILTER视图中FILTERED_ROWS远小于UNFILTERED_ROWS可确认其真实生效。

为什么Bloom Filter在Oracle 19c中对JOIN有效
Bloom Filter不是“自动开箱即用”的加速器,它只在特定条件下被优化器主动启用:哈希连接(HASH JOIN)场景 + 驱动表(build side)数据量适中 + 探测表(probe side)足够大。它的核心价值是把“本该在JOIN时才过滤的数据”,提前下推到扫描阶段——比如客户表过滤出中国客户后,立刻生成一个轻量集合(Bloom Filter),让订单表在全表扫描前就跳过大量无关行。
注意:V$SQL_JOIN_FILTER视图才是你确认它是否真起作用的唯一依据;执行计划里看到Using join buffer (hash join with bloom filter)只是线索,不是证据。
如何确认Bloom Filter是否生效
别只看执行计划,要查运行时真实行为:
- 执行查询后立即查
V$SQL_JOIN_FILTER,重点看FILTERED_ROWS和UNFILTERED_ROWS字段——如果前者远小于后者(比如10万 vs 1亿),说明过滤效果显著 - 检查
SQL_ID是否匹配你刚跑的语句,避免查错会话 - 若
FILTERED_ROWS为0或接近UNFILTERED_ROWS,大概率是驱动表太小(WHERE条件写在了JOIN之后、或用了函数包裹连接列)
哪些参数会影响Bloom Filter开关
Oracle 19c默认开启Bloom Filter,但有两个关键开关可能把它关掉:
-
_bloom_filter_enabled:系统级隐含参数,默认TRUE,设为FALSE会全局禁用——除非你明确测出它拖慢某类小表JOIN,否则别碰 -
loose_bloom_filter_enabled:显式控制参数,ON(默认)/OFF,支持ALTER SESSION级别设置。临时关闭可对比性能:ALTER SESSION SET loose_bloom_filter_enabled = OFF;
注意:loose_bloom_filter_enabled只影响“松散型”Bloom Filter(适用于并行或数据倾斜场景),而标准哈希连接用的是严格模式,受_bloom_filter_enabled控制。
容易被忽略的前置条件
Bloom Filter不是独立存在的优化项,它依赖三个底层支撑点:
- 驱动表必须走索引或高效过滤——如果
customer表靠c_nation = 'CHINA'筛选,但c_nation没索引,优化器可能放弃哈希连接,改走嵌套循环,Bloom Filter直接失效 - 统计信息必须准——
DBMS_STATS.GATHER_TABLE_STATS没跑过,优化器估算错驱动表大小,可能认为不值得建Filter - 连接列不能有隐式类型转换——比如
orders.o_custkey是NUMBER,customer.c_custkey是VARCHAR2,Bloom Filter无法构造可靠哈希值,会被跳过
真正卡住Bloom Filter的,往往不是参数没开,而是驱动表没被真正“裁剪”干净。


















