ApsaraDB for SelectDB prend en charge trois modèles de données. Choisissez le modèle approprié avant de créer une table, car ce choix est définitif.
| Modèle | Cas d'usage idéal | Limitation principale |
|---|---|---|
| Modèle de clé d'agrégation | Requêtes de rapports à schéma fixe, métriques pré-agrégées | COUNT(*) est coûteux ; chaque colonne de valeur est liée à un seul type d'agrégation |
| Modèle de clé unique | Données relationnelles nécessitant l'unicité de la clé primaire (commandes, profils utilisateur) | Pré-agrégation ROLLUP impossible |
| Modèle de clé dupliquée | Requêtes ad hoc, analyse de journaux, stockage de données brutes | Aucune pré-agrégation ; aucune déduplication automatique |
Contexte
Dans ApsaraDB for SelectDB, les tables comportent des lignes et des colonnes. Ces dernières se divisent en deux catégories :
Colonnes de clé : correspondent aux colonnes de dimension. Elles sont définies après les mots-clés
DUPLICATE KEY,AGGREGATE KEYouUNIQUE KEYdans une instructionCREATE TABLE.Colonnes de valeur : correspondent aux colonnes de métrique. Il s'agit de toutes les colonnes non répertoriées comme colonnes de clé.
Ces deux catégories correspondent directement aux trois modèles de données.
Modèle de clé d'agrégation
Le modèle de clé d'agrégation pré-agrège les données lors de l'écriture. Lorsque vous importez des lignes partageant des valeurs identiques dans toutes les colonnes de clé, SelectDB les fusionne en une seule ligne. Chaque colonne de valeur est agrégée selon la fonction spécifiée dans l'instruction CREATE TABLE.
Ce modèle convient aux requêtes de rapports avec des schémas d'agrégation fixes, par exemple pour les utilisateurs actifs quotidiens ou les revenus par région. Si vos requêtes impliquent des logiques d'agrégation variables, ou si vous avez besoin d'un COUNT(*) rapide, privilégiez le modèle de clé dupliquée ou le modèle de clé unique avec MoW. Consultez la section Limitations du modèle de clé d'agrégation pour plus de détails.
Types d'agrégation
| Type d'agrégation | Description |
|---|---|
SUM |
Calcule la somme sur l'ensemble des lignes. S'applique aux valeurs numériques. |
MIN |
Conserve la valeur minimale. S'applique aux valeurs numériques. |
MAX |
Conserve la valeur maximale. S'applique aux valeurs numériques. |
REPLACE |
Remplace la valeur précédente par la nouvelle valeur importée. Pour les lignes ayant les mêmes colonnes de clé, les valeurs sont remplacées selon l'ordre d'importation. |
REPLACE_IF_NOT_NULL |
Identique à REPLACE, mais ignore les valeurs null. Spécifiez null (et non une chaîne vide) comme valeur par défaut de la colonne ; sinon, les chaînes vides seront écrasées. |
HLL_UNION |
Agrège les colonnes de type HyperLogLog (HLL) à l'aide de l'algorithme HLL. |
BITMAP_UNION |
Agrège les colonnes BITMAP via une agrégation par union. |
Exemple 1 : Agrégation de base lors de l'importation
La table example_tbl1 enregistre les données de visite des utilisateurs. Les colonnes de clé (user_id, date, city, age, sex) identifient les enregistrements uniques ; les colonnes de valeur stockent les métriques.
| Nom de la colonne | Type | Type d'agrégation | Commentaire |
|---|---|---|---|
| user_id | LARGEINT | N/A | ID de l'utilisateur. |
| date | DATE | N/A | Date d'écriture des données dans la table. |
| city | VARCHAR(20) | N/A | Ville de résidence de l'utilisateur. |
| age | SMALLINT | N/A | Âge de l'utilisateur. |
| sex | TINYINT | N/A | Genre de l'utilisateur. |
| last_visit_date | DATETIME | REPLACE | Dernière visite de l'utilisateur. |
| cost | BIGINT | SUM | Montant dépensé par l'utilisateur. |
| max_dwell_time | INT | MAX | Temps de présence maximum de l'utilisateur. |
| min_dwell_time | INT | MIN | Temps de présence minimum de l'utilisateur. |
CREATE TABLE IF NOT EXISTS test.example_tbl1
(
`user_id` LARGEINT NOT NULL COMMENT "The user ID",
`date` DATE NOT NULL COMMENT "The date on which data is written to the table",
`city` VARCHAR(20) COMMENT "The city in which the user resides",
`age` SMALLINT COMMENT "The age of the user",
`sex` TINYINT COMMENT "The gender of the user",
`last_visit_date` DATETIME REPLACE DEFAULT "1970-01-01 00:00:00" COMMENT "The last time when the user paid a visit",
`cost` BIGINT SUM DEFAULT "0" COMMENT "The amount of money that the user spends",
`max_dwell_time` INT MAX DEFAULT "0" COMMENT "The maximum dwell time of the user",
`min_dwell_time` INT MIN DEFAULT "99999" COMMENT "The minimum dwell time of the user"
)
AGGREGATE KEY(`user_id`, `date`, `city`, `age`, `sex`)
DISTRIBUTED BY HASH(`user_id`) BUCKETS 16;
Insérez les lignes suivantes :
| user_id | date | city | age | sex | last_visit_date | cost | max_dwell_time | min_dwell_time |
|---|---|---|---|---|---|---|---|---|
| 10000 | 2017-10-01 | Beijing | 20 | 0 | 2017-10-01 06:00:00 | 20 | 10 | 10 |
| 10000 | 2017-10-01 | Beijing | 20 | 0 | 2017-10-01 07:00:00 | 15 | 2 | 2 |
| 10001 | 2017-10-01 | Beijing | 30 | 1 | 2017-10-01 17:05:45 | 2 | 22 | 22 |
| 10002 | 2017-10-02 | Shanghai | 20 | 1 | 2017-10-02 12:59:12 | 200 | 5 | 5 |
| 10003 | 2017-10-02 | Guangzhou | 32 | 0 | 2017-10-02 11:20:00 | 30 | 11 | 11 |
| 10004 | 2017-10-01 | Shenzhen | 35 | 0 | 2017-10-01 10:00:15 | 100 | 3 | 3 |
| 10004 | 2017-10-03 | Shenzhen | 35 | 0 | 2017-10-03 10:20:22 | 11 | 6 | 6 |
INSERT INTO example_db.example_tbl_agg1 VALUES
(10000,"2017-10-01","Beijing",20,0,"2017-10-01 06:00:00",20,10,10),
(10000,"2017-10-01","Beijing",20,0,"2017-10-01 07:00:00",15,2,2),
(10001,"2017-10-01","Beijing",30,1,"2017-10-01 17:05:45",2,22,22),
(10002,"2017-10-02","Shanghai",20,1,"2017-10-02 12:59:12",200,5,5),
(10003,"2017-10-02","Guangzhou",32,0,"2017-10-02 11:20:00",30,11,11),
(10004,"2017-10-01","Shenzhen",35,0,"2017-10-01 10:00:15",100,3,3),
(10004,"2017-10-03","Shenzhen",35,0,"2017-10-03 10:20:22",11,6,6);
Après l'importation, SelectDB stocke une seule ligne agrégée pour l'utilisateur 10000 (les lignes 1 et 2 partagent les mêmes colonnes de clé). Les autres utilisateurs ayant des clés uniques, leurs lignes restent inchangées :
| user_id | date | city | age | sex | last_visit_date | cost | max_dwell_time | min_dwell_time |
|---|---|---|---|---|---|---|---|---|
| 10000 | 2017-10-01 | Beijing | 20 | 0 | 2017-10-01 07:00:00 | 35 | 10 | 2 |
| 10001 | 2017-10-01 | Beijing | 30 | 1 | 2017-10-01 17:05:45 | 2 | 22 | 22 |
| 10002 | 2017-10-02 | Shanghai | 20 | 1 | 2017-10-02 12:59:12 | 200 | 5 | 5 |
| 10003 | 2017-10-02 | Guangzhou | 32 | 0 | 2017-10-02 11:20:00 | 30 | 11 | 11 |
| 10004 | 2017-10-01 | Shenzhen | 35 | 0 | 2017-10-01 10:00:15 | 100 | 3 | 3 |
| 10004 | 2017-10-03 | Shenzhen | 35 | 0 | 2017-10-03 10:20:22 | 11 | 6 | 6 |
Agrégation de la ligne de l'utilisateur 10000 :
-
last_visit_date (
REPLACE) :2017-10-01 06:00:00est remplacé par2017-10-01 07:00:00.Lorsque le type
REPLACEs'applique au sein d'un même lot d'importation, l'ordre de remplacement n'est pas garanti. La valeur stockée peut correspondre à l'un ou l'autre horodatage. Entre différents lots, le lot le plus récent l'emporte toujours. cost (
SUM) : 20 + 15 = 35.max_dwell_time (
MAX) : max(10, 2) = 10.min_dwell_time (
MIN) : min(10, 2) = 2.
Une fois l'agrégation terminée, les lignes brutes d'origine disparaissent du stockage.
Exemple 2 : Agrégation de nouvelles données avec des données existantes
Cet exemple illustre l'agrégation par SelectDB d'un second lot d'importation avec des données déjà stockées.
Créez example_tbl2 (même schéma que example_tbl1) :
CREATE TABLE IF NOT EXISTS test.example_tbl2
(
`user_id` LARGEINT NOT NULL COMMENT "The user ID",
`date` DATE NOT NULL COMMENT "The date on which data is written to the table",
`city` VARCHAR(20) COMMENT "The city in which the user resides",
`age` SMALLINT COMMENT "The age of the user",
`sex` TINYINT COMMENT "The gender of the user",
`last_visit_date` DATETIME REPLACE DEFAULT "1970-01-01 00:00:00" COMMENT "The last time when the user paid a visit",
`cost` BIGINT SUM DEFAULT "0" COMMENT "The amount of money that the user spends",
`max_dwell_time` INT MAX DEFAULT "0" COMMENT "The maximum dwell time of the user",
`min_dwell_time` INT MIN DEFAULT "99999" COMMENT "The minimum dwell time of the user"
)
AGGREGATE KEY(`user_id`, `date`, `city`, `age`, `sex`)
DISTRIBUTED BY HASH(`user_id`) BUCKETS 16;
Lot d'importation 1 :
INSERT INTO test.example_tbl2 VALUES
(10000,"2017-10-01","Beijing",20,0,"2017-10-01 06:00:00",20,10,10),
(10000,"2017-10-01","Beijing",20,0,"2017-10-01 07:00:00",15,2,2),
(10001,"2017-10-01","Beijing",30,1,"2017-10-01 17:05:45",2,22,22),
(10002,"2017-10-02","Shanghai",20,1,"2017-10-02 12:59:12",200,5,5),
(10003,"2017-10-02","Guangzhou",32,0,"2017-10-02 11:20:00",30,11,11),
(10004,"2017-10-01","Shenzhen",35,0,"2017-10-01 10:00:15",100,3,3),
(10004,"2017-10-03","Shenzhen",35,0,"2017-10-03 10:20:22",11,6,6);
Lot d'importation 2 (ajoute de nouvelles données pour l'utilisateur 10004 et introduit l'utilisateur 10005) :
INSERT INTO test.example_tbl2 VALUES
(10004,"2017-10-03","Shenzhen",35,0,"2017-10-03 11:22:00",44,19,19),
(10005,"2017-10-03","Changsha",29,1,"2017-10-03 18:11:02",3,1,1);
État final stocké :
| user_id | date | city | age | sex | last_visit_date | cost | max_dwell_time | min_dwell_time |
|---|---|---|---|---|---|---|---|---|
| 10000 | 2017-10-01 | Beijing | 20 | 0 | 2017-10-01 07:00:00 | 35 | 10 | 2 |
| 10001 | 2017-10-01 | Beijing | 30 | 1 | 2017-10-01 17:05:45 | 2 | 22 | 22 |
| 10002 | 2017-10-02 | Shanghai | 20 | 1 | 2017-10-02 12:59:12 | 200 | 5 | 5 |
| 10003 | 2017-10-02 | Guangzhou | 32 | 0 | 2017-10-02 11:20:00 | 30 | 11 | 11 |
| 10004 | 2017-10-01 | Shenzhen | 35 | 0 | 2017-10-01 10:00:15 | 100 | 3 | 3 |
| 10004 | 2017-10-03 | Shenzhen | 35 | 0 | 2017-10-03 11:22:00 | 55 | 19 | 6 |
| 10005 | 2017-10-03 | Changsha | 29 | 1 | 2017-10-03 18:11:02 | 3 | 1 | 1 |
La ligne de l'utilisateur 10004 pour le 2017-10-03 est agrégée sur les deux lots (cost : 11 + 44 = 55 ; max_dwell_time : max(6, 19) = 19 ; min_dwell_time : min(6, 19) = 6). L'utilisateur 10005 étant nouveau, sa ligne est insérée telle quelle.
L'agrégation dans ApsaraDB for SelectDB comporte trois étapes :
Étape ETL (extraction, transformation et chargement) : chaque lot d'importation est agrégé en interne avant écriture.
Étape de compactage des données : le cluster de calcul fusionne en arrière-plan les données issues de différents lots d'importation.
Étape de requête : les données non agrégées restantes sont agrégées lors de la requête.
Le degré d'agrégation à tout instant est transparent. Considérez toujours que les données interrogées sont entièrement agrégées.
Exemple 3 : Conservation des données détaillées avec le modèle de clé d'agrégation
L'ajout d'une colonne à haute cardinalité aux colonnes de clé empêche les lignes de partager la même clé. Cela permet de conserver toutes les données brutes tout en utilisant le modèle de clé d'agrégation.
Ajoutez une colonne timestamp (précise à la seconde) à la clé :
CREATE TABLE IF NOT EXISTS test.example_tbl3
(
`user_id` LARGEINT NOT NULL COMMENT "The user ID",
`date` DATE NOT NULL COMMENT "The date on which data is written to the table",
`timestamp` DATETIME NOT NULL COMMENT "The time when data is written to the table, which is accurate to seconds",
`city` VARCHAR(20) COMMENT "The city in which the user resides",
`age` SMALLINT COMMENT "The age of the user",
`sex` TINYINT COMMENT "The gender of the user",
`last_visit_date` DATETIME REPLACE DEFAULT "1970-01-01 00:00:00" COMMENT "The last time when the user paid a visit",
`cost` BIGINT SUM DEFAULT "0" COMMENT "The amount of money that the user spends",
`max_dwell_time` INT MAX DEFAULT "0" COMMENT "The maximum dwell time of the user",
`min_dwell_time` INT MIN DEFAULT "99999" COMMENT "The minimum dwell time of the user"
)
AGGREGATE KEY(`user_id`, `date`, `timestamp`, `city`, `age`, `sex`)
DISTRIBUTED BY HASH(`user_id`) BUCKETS 16;
Chaque ligne possédant un timestamp unique, aucune paire de lignes ne partage jamais les mêmes colonnes de clé. Par conséquent, aucune agrégation ne se produit et toutes les données brutes sont conservées.
Limitations du modèle de clé d'agrégation
Le modèle de clé d'agrégation présentant toujours des données entièrement agrégées, certaines requêtes peuvent produire des résultats inattendus ou entraîner des coûts élevés.
Surcharge de COUNT(*)
Prenons une table example_tbl8 avec le schéma suivant :
| Nom de la colonne | Type | Type d'agrégation | Commentaire |
|---|---|---|---|
| user_id | LARGEINT | N/A | ID de l'utilisateur. |
| date | DATE | N/A | Date d'écriture des données dans la table. |
| cost | BIGINT | SUM | Montant dépensé par l'utilisateur. |
Importez deux lots :
Lot 1 :
| user_id | date | cost |
|---|---|---|
| 10001 | 2017-11-20 | 50 |
| 10002 | 2017-11-21 | 39 |
Lot 2 :
| user_id | date | cost |
|---|---|---|
| 10001 | 2017-11-20 | 1 |
| 10001 | 2017-11-21 | 5 |
| 10003 | 2017-11-22 | 22 |
Les cinq lignes d'origine peuvent encore exister dans le stockage sous-jacent avant le compactage. L'exécution de COUNT(*) :
SELECT COUNT(*) FROM example_tbl8;
Résultat attendu : 4 (quatre combinaisons de clés uniques). Cependant, si SelectDB analyse uniquement la colonne user_id et ignore l'agrégation, il renvoie 3. S'il compte toutes les lignes non compactées, il renvoie 5. Les deux résultats sont incorrects.
Pour obtenir le résultat correct, le moteur de requête doit analyser toutes les colonnes de clé (user_id et date) et les agréger. Cela implique une analyse complète des clés pour chaque appel à COUNT(*).
Solution de contournement : Ajoutez une colonne count avec une valeur fixe de 1 et un type d'agrégation SUM :
| Nom de la colonne | Type | Type d'agrégation | Commentaire |
|---|---|---|---|
| user_id | BIGINT | N/A | ID de l'utilisateur. |
| date | DATE | N/A | Date d'écriture des données dans la table. |
| cost | BIGINT | SUM | Montant dépensé par l'utilisateur. |
| count | BIGINT | SUM | Compteur de lignes. |
SELECT SUM(count) FROM table; équivaut à SELECT COUNT(*) FROM table; et s'exécute beaucoup plus rapidement. Notez que cette approche ne prend pas en charge la réimportation de lignes avec les mêmes colonnes de clé, car cela gonflerait le compteur.
Vous pouvez également définir le type d'agrégation de la colonne count sur REPLACE avec une valeur fixe de 1. Cela produit le même résultat que COUNT(*) et permet de réimporter des clés dupliquées.
Sémantique des requêtes d'agrégation
Chaque colonne de valeur est liée à un seul type d'agrégation lors de la création de la table. L'exécution d'une fonction d'agrégation différente sur une colonne de valeur peut retourner des résultats sémantiquement incorrects. Concevez donc le schéma en fonction des types d'agrégation requis.
Modèle de clé unique
Contrairement au modèle de clé d'agrégation, le modèle de clé unique impose l'unicité de la clé primaire au lieu d'agréger les valeurs. Lorsque de nouvelles lignes arrivent avec les mêmes colonnes de clé que des lignes existantes, seule la dernière ligne importée est conservée.
Privilégiez ce modèle pour les données relationnelles avec des exigences d'unicité, telles que les commandes ou les profils utilisateur. Il ne prend pas en charge la pré-agrégation ROLLUP.
ApsaraDB for SelectDB propose deux méthodes d'implémentation :
Merge on Write (MoW) : supprime les doublons pendant l'étape d'importation. Recommandé pour des performances de requête optimales.
Merge on Read (MoR) : applique la déduplication lors de la requête.
MoW (recommandé)
MoW marque les lignes écrasées comme supprimées lors de l'importation et écrit directement les données les plus récentes. Lors de la requête, les lignes supprimées sont filtrées sans aucune opération de fusion. Cela élimine la surcharge d'agrégation de MoR et permet le pushdown de prédicats dans la plupart des scénarios, ce qui accélère les requêtes d'agrégation.
MoW est désactivé par défaut dans ApsaraDB for SelectDB V3.0. Activez-le en définissant "enable_unique_key_merge_on_write" = "true" lors de la création de la table.
CREATE TABLE IF NOT EXISTS test.example_tbl6
(
`user_id` LARGEINT NOT NULL COMMENT "The user ID",
`username` VARCHAR(50) NOT NULL COMMENT "The nickname of the user",
`city` VARCHAR(20) COMMENT "The city in which the user resides",
`age` SMALLINT COMMENT "The age of the user",
`sex` TINYINT COMMENT "The gender of the user",
`phone` LARGEINT COMMENT "The phone number of the user",
`address` VARCHAR(500) COMMENT "The address of the user",
`register_time` DATETIME COMMENT "The time when the user is registered"
)
UNIQUE KEY(`user_id`, `username`)
DISTRIBUTED BY HASH(`user_id`) BUCKETS 16
PROPERTIES (
"enable_unique_key_merge_on_write" = "true"
);
MoR ne peut pas être mis à niveau de manière transparente vers MoW, car ils organisent les données différemment. Pour migrer, utilisez INSERT INTO unique-mow-table SELECT * FROM source_table afin d'importer les données existantes dans une nouvelle table MoW.
Le signe de suppression unique et la colonne de séquence fonctionnent toujours lorsque MoW est activé.
MoR
MoR applique la logique de déduplication lors de la requête en fusionnant les données à la lecture. Cela équivaut au modèle de clé d'agrégation avec toutes les colonnes de valeur définies sur REPLACE.
CREATE TABLE IF NOT EXISTS test.example_tbl4
(
`user_id` LARGEINT NOT NULL COMMENT "The user ID",
`username` VARCHAR(50) NOT NULL COMMENT "The nickname of the user",
`city` VARCHAR(20) COMMENT "The city in which the user resides",
`age` SMALLINT COMMENT "The age of the user",
`sex` TINYINT COMMENT "The gender of the user",
`phone` LARGEINT COMMENT "The phone number of the user",
`address` VARCHAR(500) COMMENT "The address of the user",
`register_time` DATETIME COMMENT "The time when the user is registered"
)
UNIQUE KEY(`user_id`, `username`)
DISTRIBUTED BY HASH(`user_id`) BUCKETS 16;
Le modèle de clé unique MoR ci-dessus est intérieurement identique au modèle de clé d'agrégation suivant, où toutes les colonnes de valeur utilisent REPLACE :
CREATE TABLE IF NOT EXISTS test.example_tbl5
(
`user_id` LARGEINT NOT NULL COMMENT "The user ID",
`username` VARCHAR(50) NOT NULL COMMENT "The nickname of the user",
`city` VARCHAR(20) REPLACE COMMENT "The city in which the user resides",
`age` SMALLINT REPLACE COMMENT "The age of the user",
`sex` TINYINT REPLACE COMMENT "The gender of the user",
`phone` LARGEINT REPLACE COMMENT "The phone number of the user",
`address` VARCHAR(500) REPLACE COMMENT "The address of the user",
`register_time` DATETIME REPLACE COMMENT "The time when the user is registered"
)
AGGREGATE KEY(`user_id`, `username`)
DISTRIBUTED BY HASH(`user_id`) BUCKETS 16;
Modèle de clé dupliquée
Le modèle de clé dupliquée se distingue des deux autres car il stocke toutes les lignes exactement telles qu'elles ont été importées, sans agrégation ni contrainte d'unicité. Plusieurs lignes avec les mêmes valeurs de colonnes de clé coexistent sans s'affecter mutuellement.
Utilisez ce modèle pour les requêtes ad hoc sur des données brutes telles que les journaux, lorsque vous avez besoin de tous les détails et que la déduplication ou la pré-agrégation n'est pas nécessaire.
Les colonnes de clé spécifiées dans l'instruction CREATE TABLE servent uniquement de clés de tri, et non d'identifiants uniques. Nous vous recommandons de sélectionner les deux à quatre premières colonnes comme clé dupliquée.
CREATE TABLE IF NOT EXISTS test.example_tbl7
(
`timestamp` DATETIME NOT NULL COMMENT "The time when the log was generated",
`type` INT NOT NULL COMMENT "The type of the log",
`error_code` INT COMMENT "The error code",
`error_msg` VARCHAR(1024) COMMENT "The error message",
`op_id` BIGINT COMMENT "The owner ID",
`op_time` DATETIME COMMENT "The time when the error was handled"
)
DUPLICATE KEY(`timestamp`, `type`, `error_code`)
DISTRIBUTED BY HASH(`type`) BUCKETS 16;
| Colonne | Type | Clé de tri | Commentaire |
|---|---|---|---|
| timestamp | DATETIME | Oui | Heure de génération du journal. |
| type | INT | Oui | Type de journal. |
| error_code | INT | Oui | Code d'erreur. |
| error_msg | VARCHAR(1024) | Non | Message d'erreur. |
| op_id | BIGINT | Non | ID du propriétaire. |
| op_time | DATETIME | Non | Heure de traitement de l'erreur. |
Colonnes de clé selon les modèles
Les colonnes de clé jouent des rôles différents selon le modèle :
| Modèle | Rôle des colonnes de clé |
|---|---|
| Modèle de clé dupliquée | Clés de tri uniquement — pas d'identifiants uniques |
| Modèle de clé d'agrégation | Clés de tri et identifiants uniques |
| Modèle de clé unique | Clés de tri et identifiants uniques |
Choisir un modèle de données
| Scénario | Modèle recommandé |
|---|---|
| Rapports d'agrégation à schéma fixe (par exemple, utilisateurs actifs quotidiens, revenus par région) | Modèle de clé d'agrégation |
| Données relationnelles avec contraintes de clé primaire (par exemple, commandes, profils utilisateur) | Modèle de clé unique (MoW) |
| Requêtes d'agrégation hautes performances sur des données à clé primaire | Modèle de clé unique avec MoW activé |
| Analyse de données brutes, requêtes de journaux, exploration ad hoc | Modèle de clé dupliquée |
| Mises à jour partielles de colonnes | Modèle de clé unique — voir Mise à jour partielle |
Quand éviter le modèle de clé d'agrégation : Ne l'utilisez pas si vos requêtes COUNT(*) doivent être rapides, ou si vous devez exécuter des fonctions d'agrégation différentes des types d'agrégation définis lors de la création de la table. Le modèle de clé d'agrégation n'est efficace que lorsque les lignes se fusionnent de manière significative. Si la plupart des lignes ont des clés uniques, la surcharge de pré-agrégation l'emporte sur les avantages.
Comment MoW améliore les performances de COUNT(*)
MoW utilise un bitmap de suppression pour suivre les lignes écrasées plutôt que d'agréger lors de la requête. En reprenant le scénario à deux lots mentionné dans la limitation du modèle de clé d'agrégation ci-dessus :
Après le lot 1 :
| user_id | date | cost | bit de suppression |
|---|---|---|---|
| 10001 | 2017-11-20 | 50 | false |
| 10002 | 2017-11-21 | 39 | false |
Après le lot 2 (la ligne dupliquée du lot 1 est marquée comme supprimée) :
| user_id | date | cost | bit de suppression |
|---|---|---|---|
| 10001 | 2017-11-20 | 50 | true |
| 10002 | 2017-11-21 | 39 | false |
| user_id | date | cost | bit de suppression |
|---|---|---|---|
| 10001 | 2017-11-20 | 1 | false |
| 10001 | 2017-11-21 | 5 | false |
| 10003 | 2017-11-22 | 22 | false |
COUNT(*) ignore les lignes avec delete bit = true et n'analyse qu'une seule colonne, retournant ainsi 4 correctement avec une surcharge minimale. Dans l'environnement de test, les requêtes COUNT(*) utilisant la méthode d'implémentation MoW du modèle de clé unique offrent des performances 10 fois supérieures à celles utilisant le modèle de clé d'agrégation.