Roaring Bitmap est un format de bitmap compressé optimisé pour les opérations ensemblistes haute performance. Utilisez-le dans AnalyticDB for MySQL pour la déduplication, le filtrage des utilisateurs basé sur des tags et les calculs de séries temporelles sur de grands volumes de données.
Quand utiliser Roaring Bitmap
Roaring Bitmap offre de meilleures performances que les requêtes standards COUNT(DISTINCT ...) lorsque chaque groupe du bitmap contient moins de 100 millions d'entrées. Pour les espaces d'UID plus vastes, augmentez le nombre de groupes en conséquence (par exemple, un espace d'UID de 10 milliards nécessite au moins 100 groupes).
Prérequis de version
| Type de table | Version minimale |
|---|---|
| Tables externes OSS | 3.1.6.4 |
| Tables internes | 3.2.1.0 |
Les versions V3.2.8.0 et ultérieures prennent en charge les données BIGINT dans Roaring Bitmap (étendant la plage de valeurs aux entiers 64 bits). Contactez le support technique pour activer cette fonctionnalité. Une fois activée, les fonctions sélectionnées acceptent les entrées BIGINT et leur type de retour passe de INTEGER à BIGINT. Pour plus de détails, consultez la section Fonctions.
Pour afficher ou mettre à jour la version de votre cluster, accédez à la section Configuration Information de la page Cluster Information dans la console AnalyticDB for MySQL.
Limitations
-
Aucune opération SELECT directe sur les colonnes ROARINGBITMAP. Utilisez UNNEST pour afficher les éléments :
SELECT * FROM unnest(RB_BUILD(ARRAY[1,2,3])); -
Les clusters antérieurs à la version V3.2.1.0 ne prennent en charge ROARINGBITMAP que dans les tables externes OSS. Pour utiliser les opérations de bitmap sur les tables internes dans ces versions, stockez les bitmaps au format VARBINARY et convertissez-les lors de l'exécution de la requête à l'aide de
RB_BUILD_VARBINARY:-- Define an internal table with VARBINARY CREATE TABLE test_rb_cstore (id INT, rb VARBINARY); -- Query using bitmap functions SELECT RB_CARDINALITY(RB_BUILD_VARBINARY(rb)) FROM test_rb_cstore;
Construire un Roaring Bitmap
Trois fonctions permettent de construire un Roaring Bitmap, chacune correspondant à une source d'entrée différente :
| Fonction | Entrée | Cas d'utilisation |
|---|---|---|
RB_BUILD(array) |
Tableau d'entiers | Construction d'un bitmap à partir d'un tableau littéral |
RB_BUILD_AGG(integer) |
Entier (agrégat) | Agrégation d'entiers au niveau des lignes dans un bitmap |
RB_BUILD_VARBINARY(varbinary) |
VARBINARY | Lecture de bitmaps stockés au format VARBINARY dans des tables internes |
Fonctions
Fonctions scalaires
| Fonction | Type d'entrée | Type de sortie | Description | Exemple |
|---|---|---|---|---|
RB_BUILD |
ARRAY(INT) ou ARRAY(BIGINT) | ROARING BITMAP | Construit un Roaring Bitmap à partir d'un tableau d'entiers. | RB_BUILD(ARRAY[1,2,3]) |
RB_BUILD_RANGE |
INT, INT ou BIGINT, BIGINT | ROARING BITMAP | Construit un Roaring Bitmap à partir d'une plage : début (inclus) à fin (exclus). | RB_BUILD_RANGE(0, 10000) |
RB_BUILD_VARBINARY |
VARBINARY | ROARING BITMAP | Construit un Roaring Bitmap à partir de données VARBINARY. | RB_BUILD_VARBINARY(RB_TO_VARBINARY(RB_BUILD(ARRAY[1,2,3]))) |
RB_CARDINALITY |
ROARING BITMAP | BIGINT | Renvoie le nombre d'éléments dans le bitmap. | RB_CARDINALITY(RB_BUILD(ARRAY[1,2,3])) |
RB_CONTAINS |
ROARING BITMAP, INT ou ROARING BITMAP, BIGINT | BOOLEAN | Renvoie true si le bitmap contient l'entier spécifié. |
RB_CONTAINS(RB_BUILD(ARRAY[1,2,3]), 3) |
RB_CONTAINS |
ROARING BITMAP, ROARING BITMAP | BOOLEAN | Renvoie true si le premier bitmap contient tous les éléments du second. |
RB_CONTAINS(RB_BUILD(ARRAY[1,2,3]), RB_BUILD(ARRAY[3])) |
RB_AND |
ROARING BITMAP, ROARING BITMAP | ROARING BITMAP | Renvoie l'intersection (AND) de deux bitmaps. | RB_AND(RB_BUILD(ARRAY[1,2,3]), RB_BUILD(ARRAY[2,3,4])) |
RB_OR |
ROARING BITMAP, ROARING BITMAP | ROARING BITMAP | Renvoie l'union (OR) de deux bitmaps. | RB_OR(RB_BUILD(ARRAY[1,2,3]), RB_BUILD(ARRAY[2,3,4])) |
RB_XOR |
ROARING BITMAP, ROARING BITMAP | ROARING BITMAP | Renvoie le OU exclusif (XOR) de deux bitmaps. | RB_XOR(RB_BUILD(ARRAY[1,2,3]), RB_BUILD(ARRAY[2,3,4])) |
RB_AND_NULL2EMPTY |
ROARING BITMAP, ROARING BITMAP | ROARING BITMAP | Opération AND avec gestion sécurisée des valeurs nulles : si une entrée est NULL, l'autre est utilisée ; si une entrée est {}, le résultat est {}. |
RB_AND_NULL2EMPTY(RB_BUILD(null), RB_BUILD(ARRAY[3,4,5])) |
RB_OR_NULL2EMPTY |
ROARING BITMAP, ROARING BITMAP | ROARING BITMAP | Opération OR avec gestion sécurisée des valeurs nulles : les entrées NULL sont traitées comme {}. |
RB_OR_NULL2EMPTY(RB_BUILD(null), RB_BUILD(ARRAY[3,4,5])) |
RB_ANDNOT_NULL2EMPTY |
ROARING BITMAP, ROARING BITMAP | ROARING BITMAP | Opération ANDNOT avec gestion sécurisée des valeurs nulles : les entrées NULL sont traitées comme {}. |
RB_ANDNOT_NULL2EMPTY(RB_BUILD(null), RB_BUILD(ARRAY[3,4,5])) |
RB_AND_CARDINALITY |
ROARING BITMAP, ROARING BITMAP | BIGINT | Renvoie la cardinalité du résultat AND. | RB_AND_CARDINALITY(RB_BUILD(ARRAY[1,2,3]), RB_BUILD(ARRAY[3,4,5])) |
RB_AND_NULL2EMPTY_CARDINALITY |
ROARING BITMAP, ROARING BITMAP | BIGINT | Renvoie la cardinalité du résultat AND ; les entrées NULL sont traitées comme {}. |
RB_AND_NULL2EMPTY_CARDINALITY(RB_BUILD(null), RB_BUILD(ARRAY[3,4,5])) |
RB_OR_CARDINALITY |
ROARING BITMAP, ROARING BITMAP | BIGINT | Renvoie la cardinalité du résultat OR. | RB_OR_CARDINALITY(RB_BUILD(ARRAY[1,2,3]), RB_BUILD(ARRAY[3,4,5])) |
RB_OR_NULL2EMPTY_CARDINALITY |
ROARING BITMAP, ROARING BITMAP | BIGINT | Renvoie la cardinalité du résultat OR ; les entrées NULL sont traitées comme {}. |
RB_OR_NULL2EMPTY_CARDINALITY(RB_BUILD(null), RB_BUILD(ARRAY[3,4,5])) |
RB_XOR_CARDINALITY |
ROARING BITMAP, ROARING BITMAP | BIGINT | Renvoie la cardinalité du résultat XOR. | RB_XOR_CARDINALITY(RB_BUILD(ARRAY[1,2,3]), RB_BUILD(ARRAY[3,4,5])) |
RB_ANDNOT_CARDINALITY |
ROARING BITMAP, ROARING BITMAP | BIGINT | Renvoie la cardinalité du résultat ANDNOT. | RB_ANDNOT_CARDINALITY(RB_BUILD(ARRAY[1,2,3]), RB_BUILD(ARRAY[3,4,5])) |
RB_ANDNOT_NULL2EMPTY_CARDINALITY |
ROARING BITMAP, ROARING BITMAP | BIGINT | Renvoie la cardinalité du résultat ANDNOT ; les entrées NULL sont traitées comme {}. |
RB_ANDNOT_NULL2EMPTY_CARDINALITY(RB_BUILD(ARRAY[1,2,3]), RB_BUILD(ARRAY[3,4,5])) |
RB_IS_EMPTY |
ROARING BITMAP | BOOLEAN | Renvoie true si le bitmap est vide. |
RB_IS_EMPTY(RB_BUILD(ARRAY[])) |
RB_CLEAR |
ROARING BITMAP, BIGINT, BIGINT | ROARING BITMAP | Supprime les éléments dans la plage spécifiée : début (inclus) à fin (exclus). | RB_CLEAR(RB_BUILD('{1,2,3}'), 2, 3) |
RB_FLIP |
ROARING BITMAP, INT, INT ou ROARING BITMAP, BIGINT, BIGINT | ROARING BITMAP | Inverse les bits dans la plage de décalage spécifiée. | RB_FLIP(RB_BUILD(ARRAY[1,2,3,4,5]), 2, 5) |
RB_MINIMUM |
ROARING BITMAP | INT ou BIGINT | Renvoie le plus petit élément. Renvoie une erreur si le bitmap est vide. | RB_MINIMUM(RB_BUILD(ARRAY[1,2,3])) |
RB_MAXIMUM |
ROARING BITMAP | INT ou BIGINT | Renvoie le plus grand élément. Renvoie une erreur si le bitmap est vide. | RB_MAXIMUM(RB_BUILD(ARRAY[1,2,3])) |
RB_RANK |
ROARING BITMAP, INT ou ROARING BITMAP, BIGINT | BIGINT | Renvoie le nombre d'éléments inférieurs ou égaux au décalage spécifié. | RB_RANK(RB_BUILD(ARRAY[1,2,3]), 2) |
RB_TO_ARRAY |
ROARING BITMAP | ARRAY(INT) | Renvoie les éléments sous forme de tableau INT. | RB_TO_ARRAY(RB_BUILD(ARRAY[1,2,3])) |
RB_TO_LONG_ARRAY |
ROARING BITMAP | ARRAY(BIGINT) | Renvoie les éléments sous forme de tableau BIGINT. | RB_TO_LONG_ARRAY(RB_BUILD(ARRAY[4,5,6])) |
RB_TO_VARBINARY |
ROARING BITMAP | VARBINARY | Renvoie le bitmap sérialisé au format VARBINARY. | RB_TO_VARBINARY(RB_BUILD(ARRAY[1,2,3])) |
RB_RANGE_CARDINALITY |
ROARING BITMAP, INT, INT ou ROARING BITMAP, BIGINT, BIGINT | BIGINT | Renvoie la cardinalité des éléments aux positions début (inclus) à fin (exclus). La position est basée sur 1. Nécessite la version 3.1.10.0 ou ultérieure. | RB_RANGE_CARDINALITY(RB_BUILD(ARRAY[1,2,3]), 2, 3) |
RB_SELECT |
ROARING BITMAP, BIGINT, BIGINT | ROARING BITMAP | Renvoie les éléments aux positions début (inclus) à fin (exclus). La position est basée sur 1. Nécessite la version 3.1.10.0 ou ultérieure. | RB_SELECT(RB_BUILD(ARRAY[1,3,4,5,7,9]), 2, 3) |
Fonctions d'agrégation
| Fonction | Type d'entrée | Type de sortie | Description | Exemple |
|---|---|---|---|---|
RB_BUILD_AGG |
INT ou BIGINT | ROARING BITMAP | Agrège les valeurs entières de plusieurs lignes dans un bitmap. | RB_CARDINALITY(RB_BUILD_AGG(1)) |
RB_OR_AGG |
ROARING BITMAP | ROARING BITMAP | Effectue une agrégation OR sur plusieurs bitmaps. | RB_CARDINALITY(RB_OR_AGG(RB_BUILD(ARRAY[1,2,3]))) |
RB_AND_AGG |
ROARING BITMAP | ROARING BITMAP | Effectue une agrégation AND sur plusieurs bitmaps. | RB_CARDINALITY(RB_AND_AGG(RB_BUILD(ARRAY[1,2,3]))) |
RB_XOR_AGG |
ROARING BITMAP | ROARING BITMAP | Effectue une agrégation XOR sur plusieurs bitmaps. | RB_CARDINALITY(RB_XOR_AGG(RB_BUILD(ARRAY[1,2,3]))) |
RB_OR_CARDINALITY_AGG |
ROARING BITMAP | INT ou BIGINT | Effectue une agrégation OR et renvoie la cardinalité. | RB_OR_CARDINALITY_AGG(RB_BUILD(ARRAY[1,2,3])) |
RB_AND_CARDINALITY_AGG |
ROARING BITMAP | INT ou BIGINT | Effectue une agrégation AND et renvoie la cardinalité. | RB_AND_CARDINALITY_AGG(RB_BUILD(ARRAY[1,2,3])) |
RB_XOR_CARDINALITY_AGG |
ROARING BITMAP | INT ou BIGINT | Effectue une agrégation XOR et renvoie la cardinalité. | RB_XOR_CARDINALITY_AGG(RB_BUILD(ARRAY[1,2,3])) |
Utilisation de base
Ces exemples montrent comment créer une table, insérer des données de bitmap et exécuter des requêtes scalaires et d'agrégation.
Table interne
-
Créez une table interne avec une colonne ROARINGBITMAP.
CREATE TABLE `test_rb` ( `id` INT, `rb` ROARINGBITMAP ); -
Insérez des données de bitmap.
INSERT INTO test_rb VALUES (1, '[1, 2, 3]'); INSERT INTO test_rb VALUES (2, '[2, 3, 4, 5, 6]'); -
Obtenez la cardinalité de chaque ligne.
SELECT id, RB_CARDINALITY(rb) FROM test_rb;+------+--------------------+ | id | rb_cardinality(rb) | +------+--------------------+ | 2 | 5 | | 1 | 3 | +------+--------------------+ -
Obtenez la cardinalité de l'union sur toutes les lignes.
SELECT RB_OR_CARDINALITY_AGG(rb) FROM test_rb;+---------------------------+ | rb_or_cardinality_agg(rb) | +---------------------------+ | 6 | +---------------------------+
Table externe
-
Créez une table externe OSS avec une colonne ROARINGBITMAP.
CREATE TABLE `test_rb` ( `id` INT, `rb` ROARINGBITMAP ) engine = 'oss' TABLE_PROPERTIES = '{ "endpoint": "oss-cn-zhangjiakou.aliyuncs.com", "accessid": "************", "accesskey": "************", "url": "oss://testBucketName/roaringbitmap/test_for_user/", "format": "parquet" }';Pour connaître les paramètres des tables externes, consultez la rubrique Table externe OSS non partitionnée.
-
Insérez des données de bitmap.
ImportantL'instruction INSERT INTO est inefficace pour les écritures à grande échelle. Pour les grands ensembles de données, générez des fichiers Parquet à l'aide d'un outil ETL et téléchargez-les sur le chemin OSS avant de créer la table externe.
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]); -
Obtenez la cardinalité de chaque ligne.
SELECT id, RB_CARDINALITY(rb) FROM test_rb;+------+--------------------+ | id | rb_cardinality(rb) | +------+--------------------+ | 2 | 4 | | 1 | 3 | +------+--------------------+ -
Obtenez la cardinalité de l'union sur toutes les lignes.
SELECT RB_OR_CARDINALITY_AGG(rb) FROM test_rb;+---------------------------+ | rb_or_cardinality_agg(rb) | +---------------------------+ | 5 | +---------------------------+
Tutoriel de profilage des utilisateurs
Ce tutoriel détaille un flux de travail complet de profilage des utilisateurs : création d'une table de tags à partir des données brutes des utilisateurs, conversion au format bitmap pour des opérations ensemblistes efficaces et exécution d'analyses multidimensionnelles.

Étape 1 : Préparer la table de tags source
-
Créez la table source
users_base.CREATE TABLE users_base ( uid INT, tag1 STRING, -- Valid values: x, y, z tag2 STRING, -- Valid values: a, b tag3 INT -- Valid values: 1 to 10 ); -
Générez 100 millions de lignes de données de test aléatoires à l'aide d'une jointure croisée de deux plages de bitmap (10 000 × 10 000 = 100 000 000 lignes).
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)) ); -
Vérifiez les données.
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 | +--------+------+------+------+
Étape 2 : Ajouter des champs de regroupement
Les opérations de bitmap dans un moteur distribué s'exécutent en parallèle sur les groupes. Ajoutez un champ user_group pour partitionner les UID entre les groupes, ainsi qu'un champ offset pour encoder la position de l'UID au sein de chaque groupe.
Cet exemple utilise 16 groupes avec la formule uid = 16 × offset + user_group :
user_group = uid % 16— le groupe auquel appartient l'UIDoffset = uid / 16— la position de l'UID au sein du groupe
Dimensionnement de vos groupes : Chaque bitmap de groupe doit contenir moins de 100 millions d'entrées. Pour un espace d'UID de 10 milliards, utilisez 100 groupes de 100 millions chacun. Ajustez le nombre de groupes en fonction des ACU de votre cluster et de l'espace total des UID.
La formule de regroupement ci-dessus est fournie à titre illustratif uniquement. Concevez votre propre fonction de regroupement en fonction de la distribution de vos données.
-
Créez la table
usersavec les champs de regroupement.CREATE TABLE users ( uid INT, tag1 STRING, tag2 STRING, tag3 INT, user_group INT, -- Grouping field: uid % 16 offset INT -- Offset field: uid / 16 ); -
Remplissez la table
usersà partir de la tableusers_base.SUBMIT JOB INSERT OVERWRITE users SELECT uid, tag1, tag2, tag3, CAST(uid % 16 AS INT), CAST(FLOOR(uid / 16) AS INT) FROM users_base; -
Vérifiez les données.
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 | +---------+------+------+------+------------+--------+
Étape 3 : Créer des tables de tags bitmap
Pour chaque dimension de tag, créez une table de tags bitmap où chaque ligne stocke un bitmap par paire (tag_value, user_group). Le bitmap encode les décalages de tous les utilisateurs correspondants dans ce groupe.
Table interne
-
Créez et remplissez la table de tags bitmap pour
tag1.CREATE TABLE `tag_tbl_1` ( `tag1` STRING, `rb` ROARINGBITMAP, `user_group` INT ); INSERT OVERWRITE tag_tbl_1 SELECT tag1, RB_BUILD_AGG(offset), user_group FROM users GROUP BY tag1, user_group; -
Vérifiez la table de tags.
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 | +------+------------+--------------------+ -
Créez et remplissez la table de tags bitmap pour
tag2.CREATE TABLE `tag_tbl_2` ( `tag2` STRING, `rb` ROARINGBITMAP, `user_group` INT ); INSERT OVERWRITE tag_tbl_2 SELECT tag2, RB_BUILD_AGG(offset), user_group FROM users GROUP BY tag2, user_group; -
Vérifiez la table de tags.
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 | +------+------------+--------------------+
Table externe
-
Créez et remplissez la table de tags bitmap pour
tag1dans OSS.CREATE TABLE `tag_tbl_1` ( `tag1` STRING, `rb` ROARINGBITMAP, `user_group` INT ) engine = 'oss' TABLE_PROPERTIES = '{ "endpoint": "oss-cn-zhangjiakou.aliyuncs.com", "accessid": "************", "accesskey": "************", "url": "oss://testBucketName/roaringbitmap/tag_tbl_1/", "format": "parquet" }'; INSERT OVERWRITE tag_tbl_1 SELECT tag1, RB_BUILD_AGG(offset), user_group FROM users GROUP BY tag1, user_group; -
Vérifiez la table de tags.
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 | +------+------------+--------------------+ -
Créez et remplissez la table de tags bitmap pour
tag2dans OSS.CREATE TABLE `tag_tbl_2` ( `tag2` STRING, `rb` ROARINGBITMAP, `user_group` INT ) engine = 'oss' TABLE_PROPERTIES = '{ "endpoint": "oss-cn-zhangjiakou.aliyuncs.com", "accessid": "************", "accesskey": "************", "url": "oss://testBucketName/roaringbitmap/tag_tbl_2/", "format": "parquet" }'; INSERT OVERWRITE tag_tbl_2 SELECT tag2, RB_BUILD_AGG(offset), user_group FROM users GROUP BY tag2, user_group; -
Vérifiez la table de tags.
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 | +------+------------+--------------------+
Étape 4 : Analyser avec les tables de tags bitmap
Les scénarios suivants présentent des modèles d'analyse courants utilisant les tables de tags bitmap créées à l'étape 3.
Scénario 1 : Filtrer et regrouper
Comptez les utilisateurs où tag1 IN ('x', 'y'), regroupés par tag2.
Toutes les requêtes suivent le même schéma : joignez les tables de tags bitmap sur user_group, appliquez les opérations ensemblistes par groupe, puis agrégez les résultats sur tous les groupes.
-
Inspectez les résultats intermédiaires par groupe.
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 | +------+------------+---------+ -
Additionnez les comptes par groupe pour obtenir les totaux finaux.
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 | +------+----------+
Scénario 2 : Intersection entre deux tables de tags bitmap
Recherchez les utilisateurs où (tag1 = 'x' OR tag1 = 'y') AND tag2 = 'b'.
Les deux entrées proviennent de tables de tags bitmap. Effectuez d'abord une agrégation OR au sein de chaque table de tags, puis appliquez l'opération AND sur les résultats des deux tables.
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 |
+------------+--------------------+
Scénario 3 : Intersection entre une table de tags bitmap et la table source
Recherchez les utilisateurs où (tag1 = 'x' OR tag1 = 'y') AND tag2 = 'b', la seconde condition étant filtrée à partir de la table brute users plutôt que d'une table de tags bitmap préconstruite.
Utilisez RB_BUILD_AGG pour construire un bitmap à la volée à partir de la table users, puis appliquez l'opération AND avec le bitmap préconstruit de tag_tbl_1.
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 |
+------------+--------------------+
Scénario 4 : Exporter les résultats bitmap vers OSS
Enregistrez les résultats bitmap du scénario 2 dans une table externe OSS pour une utilisation en aval.
-
Créez la table de sortie.
CREATE TABLE `tag_tbl_3` ( `user_group` INT, `rb` ROARINGBITMAP ) engine = 'oss' TABLE_PROPERTIES = '{ "endpoint": "oss-cn-zhangjiakou.aliyuncs.com", "accessid": "************", "accesskey": "************", "url": "oss://testBucketName/roaringbitmap/tag_tbl_3/", "format": "parquet" }'; -
Écrivez les résultats du scénario 2 dans
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;Une fois la requête terminée, le résultat est stocké au format Parquet à l'emplacement
oss://testBucketName/roaringbitmap/tag_tbl_3/.
Scénario 5 : Accélérer les requêtes avec une table de cache interne (pour les tables externes)
Importez les données bitmap d'une table externe OSS dans une table interne pour accélérer les requêtes répétées. Étant donné que les tables internes antérieures à la version V3.2.1.0 ne prennent pas en charge nativement le type ROARINGBITMAP, stockez les bitmaps au format VARBINARY et convertissez-les lors de l'exécution de la requête.
-
Créez la table de cache interne avec une colonne VARBINARY pour le bitmap.
CREATE TABLE `tag_tbl_1_cstore` ( `tag1` VARCHAR, `rb` VARBINARY, `user_group` INT ); -
Importez depuis la table OSS en sérialisant chaque bitmap au format VARBINARY.
INSERT INTO tag_tbl_1_cstore SELECT tag1, RB_TO_VARBINARY(rb), user_group FROM tag_tbl_1; -
Interrogez la table de cache en désérialisant le format VARBINARY vers des bitmaps lors de l'exécution de la requête.
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 | +------+------------+---------------------------------------------------+