Roaring ビットマップは効率的に圧縮されたビットマップであり、さまざまなプログラミング言語やビッグデータプラットフォームで、重複排除、タグベースのフィルタリング、時系列データの計算に広く使用されています。このトピックでは、Roaring ビットマップ関数の使用方法について説明します。
サポートされているバージョン
V3.1.6.4 以降の AnalyticDB for MySQL クラスタの場合、ROARING BITMAP タイプと Roaring ビットマップ関数は Object Storage Service (OSS) 外部テーブルでサポートされています。
V3.2.1.0 以降の AnalyticDB for MySQL クラスタの場合、ROARING BITMAP タイプと Roaring ビットマップ関数は OSS 外部テーブルと AnalyticDB for MySQL 内部テーブルでサポートされています。
表示および更新するには、AnalyticDB for MySQL Data Warehouse Edition クラスタの マイナーバージョン については、AnalyticDB for MySQL コンソール にログインし、構成情報 セクションの クラスター情報 ページ に移動します。 詳細については、「クラスタのマイナーバージョンを更新する」をご参照ください。
制限事項
AnalyticDB for MySQL で Roaring ビットマップ関数を使用する場合は、次の制限事項に注意してください。
SELECT 文を実行して ROARING BITMAP タイプのフィールドのデータをクエリすることはできません。UNNEST 演算子を使用して、ROARING BITMAP タイプのフィールドの要素をクエリする必要があります。サンプル文:
SELECT * FROM unnest(RB_BUILD(ARRAY[1,2,3]));
V3.2.1.0 より前のバージョンの AnalyticDB for MySQL クラスタの場合、ROARING BITMAP タイプは OSS 外部テーブルでのみサポートされており、ROARING BITMAP タイプの列を含む AnalyticDB for MySQL 内部テーブルを作成することはできません。AnalyticDB for MySQL 内部テーブルで Roaring ビットマップ関数を使用する場合は、最初に
RB_BUILD_VARBINARY
関数を使用して VARBINARY データを ROARING BITMAP タイプに変換します。サンプル文:// 内部テーブルを作成します。 CREATE TABLE test_rb_cstore (id INT, rb VARBINARY); // Roaring ビットマップ関数を呼び出します。 SELECT RB_CARDINALITY(RB_BUILD_VARBINARY(rb)) FROM test_rb_cstore;
関数
Roaring ビットマップ関数には、スカラー関数と集約関数が含まれます。
スカラー関数
関数 | 入力データ型 | 出力データ型 | 説明 | 例 |
RB_BUILD | INT | ROARING BITMAP | 整数配列から Roaring ビットマップを生成します。 |
|
RB_BUILD_RANGE | INT,INT | ROARING BITMAP | 開始値 (含む) から終了値 (含まない) までの整数範囲に基づいて Roaring ビットマップを生成します。 |
|
RB_BUILD_VARBINARY | VARBINARY | ROARING BITMAP | VARBINARY データから Roaring ビットマップを生成します。 |
|
RB_CARDINALITY | ROARING BITMAP | BIGINT | Roaring ビットマップのカーディナリティを計算します。 |
|
RB_CONTAINS | ROARING BITMAP, INT | BOOLEAN | Roaring ビットマップに整数が含まれているかどうかを確認します。 |
|
RB_AND | ROARING BITMAP, ROARING BITMAP | ROARING BITMAP | 2 つの Roaring ビットマップの積集合を取得します。 |
|
RB_OR | ROARING BITMAP, ROARING BITMAP | ROARING BITMAP | 2 つの Roaring ビットマップの和集合を取得します。 |
|
RB_XOR | ROARING BITMAP, ROARING BITMAP | ROARING BITMAP | 2 つの Roaring ビットマップの XOR 値を取得します。 |
|
RB_AND_NULL2EMPTY | ROARING BITMAP, ROARING BITMAP | ROARING BITMAP | AND 演算を実行します。パラメータの入力値が null の場合、関数は別のパラメータの入力値を出力として使用します。パラメータの入力値が空の波括弧のペア ( |
|
RB_OR_NULL2EMPTY | ROARING BITMAP, ROARING BITMAP | ROARING BITMAP | OR 演算を実行します。入力値が null の場合、関数は空の波括弧 ({}) を入力として使用します。 |
|
RB_ANDNOT_NULL2EMPTY | ROARING BITMAP, ROARING BITMAP | ROARING BITMAP | ANDNOT 演算を実行します。入力値が null の場合、関数は空の波括弧 ({}) を入力として使用します。 |
|
RB_AND_CARDINALITY | ROARING BITMAP, ROARING BITMAP | INTEGER | 2 つの Roaring ビットマップに対して AND 演算を実行してカーディナリティを計算します。 |
|
RB_AND_NULL2EMPTY_CARDINALITY | ROARING BITMAP, ROARING BITMAP | INTEGER | 2 つの Roaring ビットマップに対して AND 演算を実行してカーディナリティを計算します。入力値が null の場合、関数は空の波括弧 ({}) を入力として使用します。 |
|
RB_OR_CARDINALITY | ROARING BITMAP, ROARING BITMAP | INTEGER | 2 つの Roaring ビットマップに対して OR 演算を実行してカーディナリティを計算します。 |
|
RB_OR_NULL2EMPTY_CARDINALITY | ROARING BITMAP, ROARING BITMAP | INTEGER | 2 つの Roaring ビットマップに対して OR 演算を実行してカーディナリティを計算します。入力値が null の場合、関数は空の波括弧 ({}) を入力として使用します。 |
|
RB_XOR_CARDINALITY | ROARING BITMAP, ROARING BITMAP | INTEGER | 2 つの Roaring ビットマップに対して XOR 演算を実行してカーディナリティを計算します。 |
|
RB_ANDNOT_CARDINALITY | ROARING BITMAP, ROARING BITMAP | INTEGER | 2 つの Roaring ビットマップに対して ANDNOT 演算を実行してカーディナリティを計算します。 |
|
RB_ANDNOT_NULL2EMPTY_CARDINALITY | ROARING BITMAP, ROARING BITMAP | INTEGER | 2 つの Roaring ビットマップに対して ANDNOT 演算を実行してカーディナリティを計算します。入力値が null の場合、関数は空の波括弧 ({}) を入力として使用します。 |
|
RB_IS_EMPTY | ROARING BITMAP | BOOLEAN | Roaring ビットマップが空かどうかを確認します。 |
|
RB_CLEAR | ROARING BITMAP,BIGINT,BIGINT | ROARING BITMAP | Roaring ビットマップ内の指定された範囲 (範囲の終点は含まない) をクリアします。 |
|
RB_CONTAINS | ROARING BITMAP, ROARING BITMAP | BOOLEAN | 最初の Roaring ビットマップに 2 番目の Roaring ビットマップが含まれているかどうかを確認します。 |
|
RB_FLIP | ROARING BITMAP, INTEGER, INTEGER | ROARING BITMAP | Roaring ビットマップ内の指定されたオフセットを反転します。 |
|
RB_MINIMUM | ROARING BITMAP | INTEGER | Roaring ビットマップ内の最小オフセットを返します。Roaring ビットマップが空の場合、エラーが返されます。 |
|
RB_MAXIMUM | ROARING BITMAP | INTEGER | Roaring ビットマップ内の最大オフセットを返します。Roaring ビットマップが空の場合、エラーが返されます。 |
|
RB_RANK | ROARING BITMAP,INTEGER | INTEGER | Roaring ビットマップ内の特定のオフセット以下の要素の数を返します。 |
|
RB_TO_ARRAY | ROARING BITMAP | INTEGER | Roaring ビットマップの作成元の整数配列を返します。 |
|
RB_TO_VARBINARY | ROARING BITMAP | VARBINARY | Roaring ビットマップの作成元の VARBINARY 配列を返します。 |
|
RB_RANGE_CARDINALITY | ROARING BITMAP, INTEGER, INTEGER | INTEGER | 開始位置 (含む) から終了位置(含まない) までの範囲のカーディナリティを返します。開始位置は 1 です。 重要 この関数は、AnalyticDB for MySQL V3.1.10.0 以降でのみサポートされています。 |
|
RB_SELECT | ROARING BITMAP, INTEGER, INTEGER | ROARING BITMAP | 開始位置 (含む) から終了位置 (含まない) までの範囲の Roaring ビットマップのオフセットを返します。 重要 この関数は、AnalyticDB for MySQL V3.1.10.0 以降でのみサポートされています。 |
|
集約関数
関数 | 入力データ型 | 出力データ型 | 説明 | 例 |
RB_BUILD_AGG | INTEGER | ROARING BITMAP | オフセットのグループから Roaring ビットマップを作成します。 |
|
RB_OR_AGG | ROARING BITMAP | ROARING BITMAP | OR 集約演算を実行します。 |
|
RB_AND_AGG | ROARING BITMAP | ROARING BITMAP | AND 集約演算を実行します。 |
|
RB_XOR_AGG | ROARING BITMAP | ROARING BITMAP | XOR 集約演算を実行します。 |
|
RB_OR_CARDINALITY_AGG | ROARING BITMAP | INTEGER | 2 つの Roaring ビットマップに対して OR 集約演算を実行してカーディナリティを計算します。 |
|
RB_AND_CARDINALITY_AGG | ROARING BITMAP | INTEGER | 2 つの Roaring ビットマップに対して AND 集約演算を実行してカーディナリティを計算します。 |
|
RB_XOR_CARDINALITY_AGG | ROARING BITMAP | INTEGER | 2 つの Roaring ビットマップに対して XOR 集約演算を実行してカーディナリティを計算します。 |
|
例
次の例では、内部テーブルと外部テーブルで Roaring ビットマップ関数を使用する方法について説明します。
内部テーブル
Roaring ビットマップをサポートする内部テーブルを作成します。
CREATE TABLE `test_rb` ( `id` INT, `rb` ROARINGBITMAP );
テーブルにデータを書き込みます。
INSERT INTO test_rb VALUES (1, '[1, 2, 3]'); INSERT INTO test_rb VALUES (2, '[2, 3, 4, 5, 6]');
Roaring ビットマップのカーディナリティを取得します。
SELECT id, RB_CARDINALITY(rb) FROM test_rb;
サンプル結果:
+------+--------------------+ | id | rb_cardinality(rb) | +------+--------------------+ | 2 | 5 | | 1 | 3 | +------+--------------------+
Roaring ビットマップに対して集約を実行します。
SELECT RB_OR_CARDINALITY_AGG(rb) FROM test_rb;
サンプル結果:
+---------------------------+ | rb_or_cardinality_agg(rb) | +---------------------------+ | 6 | +---------------------------+
外部テーブル
Roaring ビットマップをサポートする外部テーブルを作成します。
CREATE TABLE `test_rb` ( `id` INT, `rb` ROARINGBITMAP ) engine = 'oss' TABLE_PROPERTIES = '{ "endpoint":"oss-cn-zhangjiakou.aliyuncs.com", "accessid":"LTAI****************"", "accesskey":"yourAccessKeySecret", "url":"oss://testBucketName/roaringbitmap/test_for_user/", "format":"parquet" }';
説明外部テーブルのパラメータについては、「外部テーブルを使用して Data Warehouse Edition にデータをインポートする」トピックの「パーティション化されていないオブジェクトの OSS 外部テーブルを作成する」セクションをご参照ください。
テーブルにデータを書き込みます。
重要INSERT INTO 文を使用してデータを書き込む方法は、パフォーマンスの高い方法ではありません。大量のデータを書き込む場合は、抽出、変換、書き出し (ETL) ツールを使用して Parquet 形式のデータファイルを生成し、OSS ディレクトリにアップロードすることをお勧めします。
INSERT INTO test_rb SELECT 1, rb_build(ARRAY[1,2,3]); INSERT INTO test_rb SELECT 2, rb_build(ARRAY[2,3,4,5]);
Roaring ビットマップのカーディナリティを取得します。
SELECT id, RB_CARDINALITY(rb) FROM test_rb;
サンプル結果:
+------+--------------------+ | id | rb_cardinality(rb) | +------+--------------------+ | 2 | 4 | | 1 | 3 | +------+--------------------+
Roaring ビットマップに対して集約を実行します。
SELECT RB_OR_CARDINALITY_AGG(rb) FROM test_rb;
サンプル結果:
+---------------------------+ | rb_or_cardinality_agg(rb) | +---------------------------+ | 5 | +---------------------------+
例: ターゲット顧客の特定
この例では、タグテーブルを Roaring ビットマップテーブルに変換し、次の図に示すように、Roaring ビットマップに基づいて分析を実行します。
手順 1: タグテーブルを準備する
テスト用に users_base という名前のタグテーブルを作成します。
CREATE TABLE users_base( uid INT, tag1 STRING, // tag1 の有効な値: x、y、z tag2 STRING, // tag2 の有効な値: a と b tag3 INT // tag3 の有効な値: 1 から 10 );
データを挿入して、1 億行のタグデータを生成します。
SUBMIT JOB INSERT OVERWRITE users_base SELECT CAST(ROW_NUMBER() OVER (ORDER BY c1) AS INT) AS uid, SUBSTRING('xyz', FLOOR(RAND() * 3) + 1, 1) AS tag1, SUBSTRING('ab', FLOOR(RAND() * 2) + 1, 1) AS tag2, CAST(FLOOR(RAND() * 10) + 1 AS INT) as tag3 FROM ( SELECT A.c1 FROM UNNEST(RB_BUILD_RANGE(0, 10000)) AS A(c1) JOIN (SELECT c1 FROM UNNEST(RB_BUILD_RANGE(0, 10000)) AS B(c1) ));
users_base テーブルから 10 行のデータをクエリします。
SELECT * FROM users_base LIMIT 10;
サンプル結果:
+--------+------+------+------+ | uid | tag1 | tag2 | tag3 | +--------+------+------+------+ | 74526 | y | b | 3 | | 75611 | z | b | 10 | | 80850 | x | b | 5 | | 81656 | z | b | 7 | | 163845 | x | b | 2 | | 167007 | y | b | 4 | | 170541 | y | b | 9 | | 213108 | x | a | 10 | | 66056 | y | b | 4 | | 67761 | z | a | 2 | +--------+------+------+------+
手順 2: タグテーブルをグループ化する
AnalyticDB for MySQL の分散コンピューティングエンジンの並列処理機能を活用するには、uid でデータをグループ化できる列を追加することをお勧めします。この例では、グループ化のために user-group という名前の列が作成されます。グループサイズは、クラスタ内の AnalyticDB Compute Unit (ACU) の総数によって異なります。
多数のグループは計算効率が高くなります。ただし、各 Roaring ビットマップに含まれる要素の数が少ない場合、システムは Roaring ビットマップの利点を十分に活用できません。
実際のシナリオでは、各グループ内のレコード数を 1 億未満に制限することをお勧めします。たとえば、uid 値の総数が 100 億の場合、それぞれ 1 億行のデータを持つ 100 個のグループを作成できます。
この例では、uid 値は 16 個のグループに分類されます。user_group 列には、uid 値を 16 で割った余り
が格納されます。offset 列には、除算の商が格納されます。offset 列は、Roaring ビットマップの計算に使用されます。uid は、次の式に基づいて計算できます。uid = 16 × offset + user_group
。
このグループ化方法はあくまでも参考です。ビジネス要件に基づいてグループ化を設計する必要があります。
グループ化用の列を含む users という名前のタグテーブルを作成します。
CREATE TABLE users( uid INT, tag1 STRING, tag2 STRING, tag3 INT, user_group INT, // グループ化フィールド。 offset INT // オフセットフィールド。 );
users_base テーブルのデータを users テーブルに書き込みます。
SUBMIT JOB INSERT OVERWRITE users SELECT uid, tag1, tag2, tag3, CAST(uid%16 AS INT), CAST(FLOOR(uid/16) AS INT) FROM users_base;
users テーブルから 10 行のデータをクエリします。
SELECT * FROM users LIMIT 10;
サンプル結果:
+---------+------+------+------+------------+--------+ | uid | tag1 | tag2 | tag3 | user_group | offset | +---------+------+------+------+------------+--------+ | 377194 | z | b | 10 | 10 | 23574 | | 309440 | x | a | 1 | 0 | 19340 | | 601745 | z | a | 7 | 1 | 37609 | | 753751 | z | b | 3 | 7 | 47109 | | 988186 | y | a | 10 | 10 | 61761 | | 883822 | x | a | 9 | 14 | 55238 | | 325065 | x | b | 6 | 9 | 20316 | | 1042875 | z | a | 10 | 11 | 65179 | | 928606 | y | b | 5 | 14 | 58037 | | 990858 | z | a | 8 | 10 | 61928 | +---------+------+------+------+------------+--------+
手順 3: Roaring ビットマップを作成する
内部テーブル
タグ 1 用の tag_tbl_1 という名前の Roaring ビットマップテーブルを作成します。
CREATE TABLE `tag_tbl_1` ( `tag1` STRING, `rb` ROARINGBITMAP, `user_group` INT );
users テーブルのデータを tag_tbl_1 テーブルに書き込みます。
INSERT OVERWRITE tag_tbl_1 SELECT tag1, RB_BUILD_AGG(offset), user_group FROM users GROUP BY tag1, user_group;
tag_tbl_1 のデータをクエリします。
SELECT tag1, user_group, RB_CARDINALITY(rb) FROM tag_tbl_1;
サンプル結果:
+------+------------+--------------------+ | tag1 | user_group | rb_cardinality(rb) | +------+------------+--------------------+ | y | 13 | 563654 | | x | 11 | 565013 | | z | 2 | 564428 | | x | 4 | 564377 | ... | z | 5 | 564333 | | x | 8 | 564808 | | x | 0 | 564228 | | y | 3 | 563325 | +------+------------+--------------------+
タグ 2 用の tag_tbl_2 という名前の Roaring ビットマップテーブルを作成します。
CREATE TABLE `tag_tbl_2` ( `tag2` STRING, `rb` ROARINGBITMAP, `user_group` INT );
users テーブルのデータを tag_tbl_2 テーブルに書き込みます。
INSERT OVERWRITE tag_tbl_2 SELECT tag2, RB_BUILD_AGG(offset), user_group FROM users GROUP BY tag2, user_group;
tag_tbl_2 のデータをクエリします。
SELECT tag2, user_group, RB_CARDINALITY(rb) FROM tag_tbl_2;
サンプル結果:
+------+------------+--------------------+ | tag2 | user_group | rb_cardinality(rb) | +------+------------+--------------------+ | a | 9 | 3123039 | | a | 5 | 3123973 | | a | 12 | 3122414 | | a | 7 | 3127218 | | a | 15 | 3125403 | ... | a | 10 | 3122698 | | b | 4 | 3126091 | | b | 3 | 3124626 | | b | 9 | 3126961 | | b | 14 | 3125351 | +------+------------+--------------------+
外部テーブル
タグ 1 用の tag_tbl_1 という名前の Roaring ビットマップテーブルを作成します。
CREATE TABLE `tag_tbl_1` ( `tag1` STRING, `rb` ROARINGBITMAP, `user_group` INT ) engine = 'oss' TABLE_PROPERTIES = '{ "endpoint":"oss-cn-zhangjiakou.aliyuncs.com", "accessid":"LTAI****************"", "accesskey":"yourAccessKeySecret", "url":"oss://testBucketName/roaringbitmap/tag_tbl_1/", "format":"parquet" }';
users テーブルのデータを tag_tbl_1 テーブルに書き込みます。
INSERT OVERWRITE tag_tbl_1 SELECT tag1, RB_BUILD_AGG(offset), user_group FROM users GROUP BY tag1, user_group;
tag_tbl_1 のデータをクエリします。
SELECT tag1, user_group, RB_CARDINALITY(rb) FROM tag_tbl_1;
サンプル結果:
+------+------------+--------------------+ | tag1 | user_group | rb_cardinality(rb) | +------+------------+--------------------+ | z | 7 | 2082608 | | x | 10 | 2082953 | | y | 7 | 2084730 | | x | 14 | 2084856 | ... | z | 15 | 2084535 | | z | 5 | 2083204 | | x | 11 | 2085239 | | z | 1 | 2084879 | +------+------------+--------------------+
タグ 2 用の tag_tbl_2 という名前の Roaring ビットマップテーブルを作成します。
CREATE TABLE `tag_tbl_2` ( `tag2` STRING, `rb` ROARINGBITMAP, `user_group` INT ) engine = 'oss' TABLE_PROPERTIES = '{ "endpoint":"oss-cn-zhangjiakou.aliyuncs.com", "accessid":"LTAI****************"", "accesskey":"yourAccessKeySecret", "url":"oss://testBucketName/roaringbitmap/tag_tbl_2/", "format":"parquet" }';
users テーブルのデータを tag_tbl_2 テーブルに書き込みます。
INSERT OVERWRITE tag_tbl_2 SELECT tag2, RB_BUILD_AGG(offset), user_group FROM users GROUP BY tag2, user_group;
tag_tbl_2 のデータをクエリします。
SELECT tag2, user_group, RB_CARDINALITY(rb) FROM tag_tbl_2;
サンプル結果:
+------+------------+--------------------+ | tag2 | user_group | rb_cardinality(rb) | +------+------------+--------------------+ | b | 11 | 3121361 | | a | 6 | 3124750 | | a | 1 | 3125433 | ... | b | 2 | 3126523 | | b | 12 | 3123452 | | a | 4 | 3126111 | | a | 13 | 3123316 | | a | 2 | 3123477 | +------+------------+--------------------+
手順 4: Roaring ビットマップに基づいて分析を実行する
シナリオ 1: フィルタリング分析
この例では、tag1 in (x, y)
を満たす tag2 の各値のユーザー数を求めます。
tag1 in (x, y)
を満たすユーザーをクエリします。SELECT tag2, t1.user_group AS user_group, RB_CARDINALITY(RB_AND(t2.rb, rb1)) AS rb FROM tag_tbl_2 AS t2 JOIN ( SELECT user_group, rb AS rb1 FROM tag_tbl_1 WHERE tag1 IN ('x', 'y')) AS t1 ON t1.user_group = t2.user_group;
サンプル結果:
+------+------------+---------+ | tag2 | user_group | rb | +------+------------+---------+ | b | 3 | 1041828 | | a | 15 | 1039859 | | a | 9 | 1039140 | | b | 1 | 1041524 | | a | 4 | 1041599 | | b | 1 | 1041381 | | b | 10 | 1041026 | | b | 6 | 1042289 | +------+------------+---------+
tag1 in (x, y)
を満たす tag2 の各値のユーザー数を求めます。SELECT tag2, SUM(cnt) FROM ( SELECT tag2, t1.user_group AS user_group, RB_CARDINALITY(RB_AND(t2.rb, rb1)) AS cnt FROM tag_tbl_2 AS t2 JOIN ( SELECT user_group, rb AS rb1 FROM tag_tbl_1 WHERE tag1 IN ('x', 'y')) AS t1 ON t1.user_group = t2.user_group ) GROUP BY tag2;
サンプル結果:
+------+----------+ | tag2 | sum(cnt) | +------+----------+ | a | 33327868 | | b | 33335220 | +------+----------+
シナリオ 2: Roaring ビットマップの積集合、和集合、XOR を計算する
tag1 = 'x' or tag1 = 'y'
を満たす tag_tbl_1 テーブルのデータと、tag2 = 'b'
を満たす tag_tbl_2 テーブルのデータを取得し、両方の条件を満たすデータを取得します。
SELECT user_group, RB_CARDINALITY(rb) FROM (
SELECT
t1.user_group AS user_group,
RB_AND(rb1, rb2) AS rb
FROM
(
SELECT
user_group,
RB_OR_AGG(rb) AS rb1
FROM
tag_tbl_1
WHERE
tag1 = 'x'
OR tag1 = 'y'
GROUP BY
user_group
) AS t1
JOIN (
SELECT
user_group,
RB_OR_AGG(rb) AS rb2
FROM
tag_tbl_2
WHERE
tag2 = 'b'
GROUP BY
user_group
) AS t2 ON t1.user_group = t2.user_group
GROUP BY user_group);
サンプル結果:
+------------+--------------------+
| user_group | rb_cardinality(rb) |
+------------+--------------------+
| 10 | 2083679 |
| 3 | 2082370 |
| 9 | 2082847 |
| 2 | 2086511 |
...
| 1 | 2082291 |
| 4 | 2083290 |
| 14 | 2083581 |
| 15 | 2084110 |
+------------+--------------------+
シナリオ 3: Roaring ビットマップと元のタグテーブルの積集合、和集合、XOR を計算する
tag1 = 'x' or tag1 = 'y'
を満たす tag_tbl_1 テーブルのデータと、tag2 = 'b'
を満たす users テーブルのデータを取得し、両方の条件を満たすデータを取得します。
SELECT user_group, RB_CARDINALITY(rb) FROM (
SELECT
t1.user_group AS user_group,
RB_AND(rb1, rb2) AS rb
FROM
(
SELECT
user_group,
RB_OR_AGG(rb) AS rb1
FROM
tag_tbl_1
WHERE
tag1 = 'x'
OR tag1 = 'y'
GROUP BY
user_group
) AS t1
JOIN (
SELECT
user_group,
RB_BUILD_AGG(offset) AS rb2
FROM
users
WHERE
tag2 = 'b'
GROUP BY
user_group
) AS t2 ON t1.user_group = t2.user_group
GROUP BY user_group);
サンプル結果:
+------------+--------------------+
| user_group | rb_cardinality(rb) |
+------------+--------------------+
| 3 | 2082370 |
| 1 | 2082291 |
| 0 | 2082383 |
| 4 | 2083290 |
| 11 | 2081662 |
| 13 | 2085280 |
...
| 14 | 2083581 |
| 15 | 2084110 |
| 9 | 2082847 |
| 8 | 2084860 |
| 5 | 2083056 |
| 7 | 2083275 |
+------------+--------------------+
シナリオ 4: OSS 外部テーブルを使用して結果を OSS にエクスポートする
計算結果のエクスポート先の tag_tbl_3 という名前のタグテーブルを作成します。
CREATE TABLE `tag_tbl_3` ( `user_group` INT, `rb` ROARINGBITMAP )engine = 'oss' TABLE_PROPERTIES = '{ "endpoint":"oss-cn-zhangjiakou.aliyuncs.com", "accessid":"LTAI****************"", "accesskey":"yourAccessKeySecret", "url":"oss://testBucketName/roaringbitmap/tag_tbl_3/", "format":"parquet" }';
シナリオ 2 の結果を tag_tbl_3 にエクスポートします。
INSERT OVERWRITE tag_tbl_3 SELECT t1.user_group AS user_group, RB_AND(rb1, rb2) AS rb FROM ( SELECT user_group, RB_OR_AGG(rb) AS rb1 FROM tag_tbl_1 WHERE tag1 = 'x' OR tag1 = 'y' GROUP BY user_group ) AS t1 JOIN ( SELECT user_group, RB_OR_AGG(rb) AS rb2 FROM tag_tbl_2 WHERE tag2 = 'b' GROUP BY user_group ) AS t2 ON t1.user_group = t2.user_group;
説明文が実行されると、ファイルは
oss://testBucketName/roaringbitmap/tag_tbl_3/
ディレクトリに Parquet ファイルとして保存されます。
シナリオ 5: 外部テーブルのクエリを高速化する
tag_tbl_1 テーブルから内部テーブルにデータをインポートして、クエリのパフォーマンスを向上させることができます。
tag_tbl_1_cstore という名前の内部テーブルを作成し、rb フィールドのデータ型を VARBINARY に設定します。
CREATE TABLE `tag_tbl_1_cstore` ( `tag1` VARCHAR, `rb` VARBINARY, `user_group` INT );
tag_tbl_1 テーブルのデータを OSS から tag_tbl_1_cstore にインポートします。
INSERT INTO tag_tbl_1_cstore SELECT tag1, RB_TO_VARBINARY(rb), user_group FROM tag_tbl_1;
tag_tbl_1_cstore テーブルのデータをクエリします。
SELECT tag1, user_group, RB_CARDINALITY(RB_OR_AGG(RB_BUILD_VARBINARY(rb))) FROM tag_tbl_1_cstore GROUP BY tag1, user_group;
サンプル結果:
+------+------------+---------------------------------------------------+ | tag1 | user_group | rb_cardinality(rb_or_agg(rb_build_varbinary(rb))) | +------+------------+---------------------------------------------------+ | y | 3 | 2082919 | | x | 9 | 2083085 | | x | 3 | 2082140 | | y | 11 | 2082268 | | z | 4 | 2082451 | ... | z | 2 | 2081560 | | y | 6 | 2082194 | | z | 7 | 2082608 | +------+------------+---------------------------------------------------+