Une vue matérialisée synchrone est un jeu de données précalculé, stocké sous forme de table spéciale dans ApsaraDB for SelectDB. Définissez-la une seule fois à l'aide d'une instruction SELECT et SelectDB l'exploite automatiquement dès qu'une requête correspondante arrive, sans aucune réécriture manuelle de votre part.
Vues matérialisées synchrones et asynchrones
Choisissez le type approprié avant de commencer la création.
| Vue matérialisée synchrone | Vue matérialisée asynchrone | |
|---|---|---|
| Prise en charge des tables de base | Table unique uniquement | Plusieurs tables |
| Prise en charge des JOIN | Non | Oui |
| Fonctions d'agrégation | Limitées (SUM, MIN, MAX, COUNT, BITMAP_UNION, HLL_UNION) | Gamme complète |
| Réécriture de requête | Automatique | Automatique |
| Stratégie d'actualisation | Synchrone : mise à jour à chaque importation de données | Asynchrone : actualisation planifiée ou manuelle |
| Cohérence des données | Toujours cohérente avec la table de base | Cohérence à terme |
Optez pour une vue matérialisée synchrone lorsque votre charge de travail cible une seule table et exige une cohérence en temps réel. Privilégiez une vue matérialisée asynchrone pour les jointures multi-tables ou une logique d'agrégation plus complexe.
Cas d'utilisation
Accélération des agrégations : Précalculez les agrégations GROUP BY exécutées fréquemment sur de grands volumes de données.
Correspondance d'index de préfixe : Créez une vue avec une colonne de tri principale différente afin de répondre aux requêtes qui ne peuvent pas exploiter l'index de préfixe de la table de base.
Pré-filtrage : Stockez un sous-ensemble filtré de la table de base pour réduire le volume de balayage.
Précalcul d'expressions : Matérialisez des colonnes calculées complexes pour que les requêtes lisent directement les résultats.
Quand créer une vue matérialisée
Créez une vue matérialisée synchrone lorsque toutes les conditions suivantes sont remplies :
La requête cible une seule table.
La requête s'exécute fréquemment.
La requête est coûteuse (agrégation lourde, balayage volumineux ou expression complexe).
Évitez de créer une vue matérialisée si l'une des situations suivantes s'applique :
La requête est déjà rapide et peu coûteuse.
Différentes fonctions d'agrégation sont nécessaires sur la même colonne (non pris en charge).
Vous possédez déjà plus de 10 vues matérialisées sur la table : chaque vue supplémentaire ralentit toutes les importations de données, car la table de base et toutes ses vues sont mises à jour simultanément.
Limites
Requêtes directes non prises en charge. Rédigez vos requêtes sur la table de base. SelectDB sélectionne automatiquement la vue matérialisée la plus adaptée.
Restriction du modèle Unique : Dans le modèle Unique, une vue matérialisée synchrone peut uniquement réorganiser les colonnes ; elle ne peut pas agréger de données.
Performance d'importation : Chaque vue matérialisée ajoute une surcharge à toute importation de données. Plus de 10 vues matérialisées sur une seule table peuvent ralentir considérablement les importations.
Créer une vue matérialisée
Syntaxe
CREATE MATERIALIZED VIEW <mv_name> AS <query>
[PROPERTIES ("key" = "value")]
Format de query :
SELECT select_expr [, select_expr ...]
FROM <base_table_name>
[GROUP BY column_name [, column_name ...]]
[ORDER BY column_name [, column_name ...]]
Paramètres
| Paramètre | Obligatoire | Description |
|---|---|---|
mv_name |
Oui | Nom de la vue matérialisée. Doit être unique par table de base. |
query |
Oui | Instruction SELECT définissant la vue matérialisée. Elle doit référencer une seule table ; les sous-requêtes sont interdites. |
properties |
Non | Configuration facultative : short_key (nombre de colonnes de tri) et timeout (délai d'expiration de construction en secondes). |
Contraintes de l'instruction SELECT :
Table unique uniquement : aucune sous-requête autorisée.
Les colonnes ne doivent inclure ni colonnes auto-incrémentées, ni constantes, expressions dupliquées ou fonctions de fenêtrage.
Si le SELECT inclut des colonnes de clé de partition ou de bucketing, ces colonnes doivent être des colonnes Key dans la vue matérialisée.
Clauses autorisées : WHERE, GROUP BY, ORDER BY.
Clauses interdites : JOIN, HAVING, LIMIT, LATERAL VIEW.
Contraintes des fonctions d'agrégation :
Les paramètres doivent être des colonnes simples ; les expressions ne sont pas prises en charge. Par exemple, sum(a) est valide, mais sum(a+b) ne l'est pas. L'utilisation de différentes fonctions d'agrégation sur la même colonne est également interdite : SELECT sum(a), min(a) FROM table est invalide.
Fonctions d'agrégation prises en charge :
| Fonction | Notes d'utilisation |
|---|---|
| SUM, MIN, MAX, COUNT | Agrégation standard. |
| BITMAP_UNION | BITMAP_UNION(TO_BITMAP(col)) : la colonne doit être de type entier (à l'exclusion de largeint). BITMAP_UNION(col) : la table de base doit utiliser le modèle Aggregate. |
| HLL_UNION | HLL_UNION(HLL_HASH(col)) : la colonne ne peut pas être de type DECIMAL. HLL_UNION(col) : la table de base doit utiliser le modèle Aggregate. |
Règles d'ajout automatique pour ORDER BY (si ORDER BY est omis) :
Vue de type agrégation : toutes les colonnes de regroupement deviennent des colonnes de tri.
Vue hors agrégation : les 36 premiers octets des colonnes deviennent des colonnes de tri.
Si moins de trois colonnes sont ajoutées automatiquement, les trois premières colonnes sont utilisées.
Si GROUP BY est spécifié, ORDER BY doit correspondre aux colonnes de regroupement.
Principes de conception
Abstraire les modèles partagés. Définissez la vue matérialisée autour de modèles d'agrégation communs à plusieurs requêtes. Une vue correspondant à une seule requête consomme de l'espace de stockage pour un bénéfice minime.
Cibler uniquement les dimensions courantes. Toutes les combinaisons de dimensions ne nécessitent pas de vue matérialisée. Concentrez-vous sur les combinaisons les plus fréquentes dans les requêtes de production.
Exemples
Les exemples suivants utilisent cette table de base :
CREATE TABLE duplicate_table (
k1 INT NULL,
k2 INT NULL,
k3 BIGINT NULL,
k4 BIGINT NULL
)
DUPLICATE KEY (k1, k2, k3, k4)
DISTRIBUTED BY HASH(k4) BUCKETS 3;
Exemple 1 : Sous-ensemble de colonnes avec préfixe réordonné
CREATE MATERIALIZED VIEW k1_k2 AS
SELECT k2, k1 FROM duplicate_table;
Résultat : une vue contenant uniquement k2 et k1, avec k2 comme colonne de tri principale. Les requêtes filtrant sur k2 peuvent utiliser l'index de préfixe de cette vue au lieu de celui de la table de base.
Exemple 2 : Ordre de tri explicite
CREATE MATERIALIZED VIEW k2_order AS
SELECT k2, k1 FROM duplicate_table ORDER BY k2;
Exemple 3 : Agrégation
CREATE MATERIALIZED VIEW k1_k2_sumk3 AS
SELECT k1, k2, sum(k3)
FROM duplicate_table
GROUP BY k1, k2;
Résultat : une vue avec k1 et k2 comme colonnes Key, et sum(k3) comme valeur agrégée. SelectDB ajoute automatiquement k1, k2 comme colonnes de tri, car GROUP BY est utilisé et ORDER BY est omis.
Vérifier l'état de création
La création d'une vue matérialisée est une opération asynchrone. Après l'envoi de l'instruction CREATE, SelectDB construit la vue en arrière-plan. Suivez la progression avec la commande suivante :
SHOW ALTER TABLE MATERIALIZED VIEW FROM <database>;
Champs du résultat :
| Champ | Description |
|---|---|
TableName |
Nom de la table de base. |
BaseIndexName |
Nom de l'index de la table de base. |
RollupIndexName |
Nom de la vue matérialisée. |
State |
État de la tâche : PENDING (planifiée), RUNNING (en cours), FINISHED (terminée), CANCELLED (annulée). |
Timeout |
Délai d'expiration de construction en secondes. |
La vue est prête à l'emploi lorsque State affiche FINISHED.
Exemple :
SHOW ALTER TABLE MATERIALIZED VIEW FROM test_db;
+--------+---------------+---------------------+---------------------+---------------+-----------------+----------+---------------+----------+------+----------+---------+
| JobId | TableName | CreateTime | FinishTime | BaseIndexName | RollupIndexName | RollupId | TransactionId | State | Msg | Progress | Timeout |
+--------+---------------+---------------------+---------------------+---------------+-----------------+----------+---------------+----------+------+----------+---------+
| 494349 | sales_records | 2020-07-30 20:04:56 | 2020-07-30 20:04:57 | sales_records | store_amt | 494350 | 133107 | FINISHED | | NULL | 2592000 |
+--------+---------------+---------------------+---------------------+---------------+-----------------+----------+---------------+----------+------+----------+---------+
Lister les vues matérialisées
Listez toutes les vues matérialisées d'une table de base ainsi que leurs schémas :
DESC <table_name> ALL;
Exemple :
DESC duplicate_table ALL;
+-----------------+---------------+---------------+--------+--------------+------+-------+---------+-------+---------+------------+-------------+
| IndexName | IndexKeysType | Field | Type | InternalType | Null | Key | Default | Extra | Visible | DefineExpr | WhereClause |
+-----------------+---------------+---------------+--------+--------------+------+-------+---------+-------+---------+------------+-------------+
| duplicate_table | DUP_KEYS | k1 | INT | INT | Yes | true | NULL | | true | | |
| | | k2 | INT | INT | Yes | true | NULL | | true | | |
| | | k3 | BIGINT | BIGINT | Yes | true | NULL | | true | | |
| | | k4 | BIGINT | BIGINT | Yes | true | NULL | | true | | |
| | | | | | | | | | | | |
| k2_order | DUP_KEYS | mv_k2 | INT | INT | Yes | true | NULL | | true | `k2` | |
| | | mv_k1 | INT | INT | Yes | false | NULL | NONE | true | `k1` | |
| | | | | | | | | | | | |
| k1_k2 | DUP_KEYS | mv_k2 | INT | INT | Yes | true | NULL | | true | `k2` | |
| | | mv_k1 | INT | INT | Yes | true | NULL | | true | `k1` | |
| | | | | | | | | | | | |
| k1_k2_sumk3 | AGG_KEYS | mv_k1 | INT | INT | Yes | true | NULL | | true | `k1` | |
| | | mv_k2 | INT | INT | Yes | true | NULL | | true | `k2` | |
| | | mva_SUM__`k3` | BIGINT | BIGINT | Yes | false | NULL | SUM | true | `k3` | |
+-----------------+---------------+---------------+--------+--------------+------+-------+---------+-------+---------+------------+-------------+
Afficher l'instruction de création
Récupérez le code SQL utilisé pour créer une vue matérialisée :
SHOW CREATE MATERIALIZED VIEW <mv_name> ON <table_name>;
Cette commande fonctionne uniquement pour les vues matérialisées existantes. Les vues supprimées ne peuvent pas être interrogées.
Exemple :
SHOW CREATE MATERIALIZED VIEW id_col1 ON table3;
+-----------+----------+----------------------------------------------------------------+
| TableName | ViewName | CreateStmt |
+-----------+----------+----------------------------------------------------------------+
| table3 | id_col1 | create materialized view id_col1 as select id,col1 from table3 |
+-----------+----------+----------------------------------------------------------------+
1 row in set (0.00 sec)
Supprimer une vue matérialisée
Annuler une création en cours
Si la tâche de création n'est pas encore terminée, annulez-la avec la commande suivante :
CANCEL ALTER TABLE MATERIALIZED VIEW FROM <database>.<table_name>;
| Paramètre | Obligatoire | Description |
|---|---|---|
database |
Oui | Base de données contenant la table de base. |
table_name |
Oui | Nom de la table de base. |
Exemple :
CANCEL ALTER TABLE MATERIALIZED VIEW FROM test_db.duplicate_table;
Si la vue est déjà construite, cette commande n'a aucun effet ; utilisez plutôt DROP.
Supprimer une vue matérialisée terminée
DROP MATERIALIZED VIEW [IF EXISTS] <mv_name> ON <table_name>;
| Paramètre | Obligatoire | Description |
|---|---|---|
IF EXISTS |
Non | Supprime l'erreur si la vue n'existe pas. |
mv_name |
Oui | Nom de la vue matérialisée à supprimer. |
table_name |
Oui | Table de base de la vue matérialisée. |
Exemple :
-- List materialized views before dropping
DESC duplicate_table ALL;
-- Drop the view named k1_k2
DROP MATERIALIZED VIEW k1_k2 ON duplicate_table;
-- Confirm the view is gone
DESC duplicate_table ALL;
Correspondance automatique des requêtes
Une fois la vue matérialisée créée et son State passé à FINISHED, toutes les requêtes existantes continuent de cibler la table de base sans modification. SelectDB sélectionne de manière transparente la vue matérialisée la plus adaptée et réécrit la requête en interne.
Le tableau de correspondance pour les fonctions d'agrégation est le suivant :
| Agrégation de la vue matérialisée | Agrégation de requête correspondante |
|---|---|
| sum | sum |
| min | min |
| max | max |
| count | count |
| bitmap_union | bitmap_union, bitmap_union_count, count(distinct) |
| hll_union | hll_raw_agg, hll_union_agg, ndv, approx_count_distinct |
Lorsqu'une agrégation bitmap ou hll correspond, SelectDB réécrit l'opérateur d'agrégation de la requête en fonction du schéma de la vue matérialisée.
Pour confirmer qu'une requête utilise bien une vue matérialisée, exécutez EXPLAIN dessus :
EXPLAIN <your_query>;
Dans la sortie, recherchez OlapScanNode. L'attribut rollup indique quel index est balayé. S'il affiche le nom de la vue matérialisée au lieu du nom de la table de base, la correspondance est confirmée. Pour plus de détails sur la lecture de la sortie EXPLAIN, consultez Query Explain.
Bonnes pratiques
Décompte distinct exact avec BITMAP_UNION
Scénario : Comptage d'utilisateurs uniques (ou de toute autre colonne entière à haute cardinalité) groupés selon plusieurs dimensions.
Requête typique :
SELECT advertiser, channel, COUNT(DISTINCT user_id)
FROM advertiser_view_record
GROUP BY advertiser, channel;
L'utilisation de COUNT(DISTINCT ...) sur de grandes tables est coûteuse. Une vue matérialisée avec BITMAP_UNION pré-déduplique les données afin que la requête lise des bitmaps agrégés plutôt que des lignes brutes.
Créer la vue :
CREATE MATERIALIZED VIEW advertiser_uv AS
SELECT advertiser, channel, bitmap_union(to_bitmap(user_id))
FROM advertiser_view_record
GROUP BY advertiser, channel;
user_idétant de type INT, enveloppez-le avecto_bitmap()avant d'appliquerbitmap_union. Cela convertit les entiers au format bitmap requis par la fonction.
Une fois la vue construite (State = FINISHED), la requête d'origine est automatiquement réécrite ainsi :
SELECT advertiser, channel, bitmap_union_count(to_bitmap(user_id))
FROM advertiser_uv
GROUP BY advertiser, channel;
Vérifier la correspondance :
EXPLAIN SELECT advertiser, channel, COUNT(DISTINCT user_id)
FROM advertiser_view_record
GROUP BY advertiser, channel;
Dans la sortie EXPLAIN, localisez OlapScanNode. Confirmez que la valeur rollup est bien advertiser_uv. Vérifiez également que count(distinct) a été réécrit en bitmap_union_count(to_bitmap).
Décompte distinct approximatif avec HLL_UNION
Scénario : Estimation de décomptes uniques lorsqu'une précision exacte n'est pas requise et que la vitesse de requête prime.
CREATE MATERIALIZED VIEW approx_uv AS
SELECT advertiser, channel, hll_union(hll_hash(user_id))
FROM advertiser_view_record
GROUP BY advertiser, channel;
Les requêtes utilisant approx_count_distinct, ndv, hll_union_agg ou hll_raw_agg sur user_id correspondent automatiquement à cette vue.
user_idne peut pas être de typeDECIMALlors de l'utilisation du formatHLL_UNION(HLL_HASH(col)).
Réorganisation de l'index de préfixe
Scénario : Une requête fréquente filtre sur une colonne qui n'est pas la colonne principale de la clé de tri de la table de base.
Si la table de base utilise DUPLICATE KEY (k1, k2, k3, k4) mais que les requêtes filtrent souvent sur k2 :
CREATE MATERIALIZED VIEW k2_order AS
SELECT k2, k1 FROM duplicate_table ORDER BY k2;
Les requêtes avec WHERE k2 = ... peuvent désormais utiliser l'index de préfixe de cette vue, ce qui réduit considérablement la plage de balayage.
Résolution des problèmes
Erreur : DATA_QUALITY_ERR: "The data quality does not satisfy, please check your data."
Cette erreur survient lorsque des problèmes de qualité des données ou des modifications de schéma entraînent un dépassement des limites de mémoire lors de la construction de la vue. Si la cause est une pression mémoire, augmentez le paramètre memory_limitation_per_thread_for_schema_change_bytes.
Deux autres causes spécifiques aux vues bitmap :
Entiers négatifs dans les données source :
BITMAP_UNIONprend uniquement en charge les entiers positifs. Si la colonne contient des valeurs négatives, la création de la vue échoue. Vérifiez les données source et filtrez ou transformez les valeurs négatives avant de créer la vue.Colonnes de chaîne : Utilisez
bitmap_hashoubitmap_hash64pour calculer une valeur de hachage à partir des colonnes de chaîne avant d'appliquerbitmap_union.
Étapes suivantes
Query Explain : comprenez la sortie EXPLAIN pour déboguer la planification des requêtes et vérifier la correspondance des vues matérialisées.