Bloom フィルターのプッシュダウンは、ハッシュ結合クエリ実行時にストレージエンジンと SQL レイヤー間で転送されるデータ量を削減し、SQL レイヤーの処理オーバーヘッドを低減して、全体的なクエリパフォーマンスを向上させます。
前提条件
開始する前に、以下の点を確認してください。
PolarDB for MySQL クラスターのバージョンが 8.0(リビジョンバージョン 8.0.2.2.3 以降)である必要があります。バージョンの確認方法については、「エンジンバージョンの照会」をご参照ください。
対象データの型が INT 型である必要があります。
仕組み
PolarDB for MySQL がハッシュ結合を実行する際、小さい方のテーブル(ビルド側テーブル)からハッシュテーブルを構築します。同時に、データベースはこのハッシュテーブルに基づいて Bloom フィルターを作成し、それをプローブエンジンにプッシュダウンします。
プローブエンジンは、Bloom フィルターを用いて、SQL レイヤーに到達する前にクエリに不要な行を事前に除外します。これにより、SQL レイヤーが処理する必要のあるデータ量が削減されます。
Bloom フィルターのプッシュダウンの有効化
loose_bloom_filter_enabled パラメーターを使用して、Bloom フィルターの有効/無効を設定できます。デフォルトでは有効になっています。
パラメーターの設定方法については、「クラスターおよびノードパラメーターの指定」をご参照ください。
| パラメーター | 適用範囲 | デフォルト値 | 有効な値 |
|---|---|---|---|
loose_bloom_filter_enabled | グローバルおよびセッション | ON | ON、OFF |
Bloom フィルターのプッシュダウンが有効になっているかの確認
パラメーターを有効化した後、ハッシュ結合クエリに対して EXPLAIN を実行します。出力結果の Extra フィールドに hash join with bloom filter が表示されている場合、Bloom フィルターが有効になっていることを確認できます。
TPC-H Q3 クエリの実行例を以下に示します。
*************************** 2. 行 ***************************
Extra: Using where; Using join buffer (hash join with bloom filter)パフォーマンステスト
以下のテスト結果は、TPC-H スキーマ(スケールファクター 1)、およびプライマリキー・インデックスなしの環境で得られたものです。Q3、Q11、Q16 の実行計画を以下に示します。各実行計画には、少なくとも 1 つのテーブルの Extra フィールドに hash join with bloom filter が表示されており、Bloom フィルターが有効であることが確認されています。
Q3
EXPLAIN
SELECT l_orderkey,
SUM(l_extendedprice * (1 - l_discount)) AS revenue,
o_orderdate,
o_shippriority
FROM customer,
orders,
lineitem
WHERE c_mktsegment = 'MACHINERY'
AND c_custkey = o_custkey
AND l_orderkey = o_orderkey
AND o_orderdate < '1995-03-10'
AND l_shipdate > '1995-03-10'
GROUP BY l_orderkey,
o_orderdate,
o_shippriority
ORDER BY revenue DESC,
o_orderdate
LIMIT 10\G
*************************** 1. 行 ***************************
id: 1
select_type: SIMPLE
table: customer
partitions: NULL
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 148463
filtered: 10.00
Extra: Using where; Using temporary; Using filesort
*************************** 2. 行 ***************************
id: 1
select_type: SIMPLE
table: orders
partitions: NULL
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 1486962
filtered: 3.33
Extra: Using where; Using join buffer (hash join with bloom filter)
*************************** 3. 行 ***************************
id: 1
select_type: SIMPLE
table: lineitem
partitions: NULL
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 5948979
filtered: 3.33
Extra: Using where; Using join buffer (hash join with bloom filter)Q11
EXPLAIN
SELECT ps_partkey,
SUM(ps_supplycost * ps_availqty) AS value
FROM partsupp,
supplier,
nation
WHERE ps_suppkey = s_suppkey
AND s_nationkey = n_nationkey
AND n_name = 'INDIA'
GROUP BY ps_partkey
HAVING SUM(ps_supplycost * ps_availqty) >
(SELECT SUM(ps_supplycost * ps_availqty) * 0.0001000000
FROM partsupp,
supplier,
nation
WHERE ps_suppkey = s_suppkey
AND s_nationkey = n_nationkey
AND n_name = 'INDIA' )
ORDER BY value DESC\G
*************************** 1. 行 ***************************
id: 1
select_type: PRIMARY
table: nation
partitions: NULL
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 25
filtered: 10.00
Extra: Using where; Using temporary; Using filesort
*************************** 2. 行 ***************************
id: 1
select_type: PRIMARY
table: supplier
partitions: NULL
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 10000
filtered: 10.00
Extra: Using where; Using join buffer (hash join with bloom filter)
*************************** 3. 行 ***************************
id: 1
select_type: PRIMARY
table: partsupp
partitions: NULL
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 791815
filtered: 10.00
Extra: Using where; Using join buffer (hash join with bloom filter)
*************************** 4. 行 ***************************
id: 2
select_type: SUBQUERY
table: nation
partitions: NULL
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 25
filtered: 10.00
Extra: Using where
*************************** 5. 行 ***************************
id: 2
select_type: SUBQUERY
table: supplier
partitions: NULL
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 10000
filtered: 10.00
Extra: Using where; Using join buffer (hash join with bloom filter)
*************************** 6. 行 ***************************
id: 2
select_type: SUBQUERY
table: partsupp
partitions: NULL
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 791815
filtered: 10.00
Extra: Using where; Using join buffer (hash join with bloom filter)Q16
EXPLAIN SELECT p_brand,
p_type,
p_size,
COUNT(DISTINCT ps_suppkey) AS supplier_cnt
FROM partsupp,
part
WHERE p_partkey = ps_partkey
AND p_brand <> 'Brand#33'
AND p_type NOT LIKE 'PROMO POLISHED%'
AND p_size IN (34,
45,
33,
42,
9,
24,
26,
7)
AND ps_suppkey NOT IN
(SELECT s_suppkey
FROM supplier
WHERE s_comment LIKE '%Customer%Complaints%' )
GROUP BY p_brand,
p_type,
p_size
ORDER BY supplier_cnt DESC,
p_brand,
p_type,
p_size\G
*************************** 1. 行 ***************************
id: 1
select_type: PRIMARY
table: part
partitions: NULL
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 198116
filtered: 40.00
Extra: Using where; Using temporary; Using filesort
*************************** 2. 行 ***************************
id: 1
select_type: PRIMARY
table: partsupp
partitions: NULL
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 791815
filtered: 10.00
Extra: Using where; Using join buffer (hash join with bloom filter)
*************************** 3. 行 ***************************
id: 2
select_type: SUBQUERY
table: supplier
partitions: NULL
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 10000
filtered: 11.11
Extra: Using whereテスト結果
以下のチャートは、Bloom フィルターを有効/無効にした場合の Q3、Q11、Q16 のクエリ実行時間(TPC-H スケールファクター 1、プライマリキーおよびインデックスなし)を比較したものです。
