Tous les produits
Search
Centre de documentation

MaxCompute:UPDATE | DELETE

Dernière mise à jour :Aug 10, 2026

MaxCompute vous permet d'utiliser les opérations DELETE et UPDATE pour supprimer ou mettre à jour des données au niveau de la ligne dans les tables transactionnelles (Transactional tables) et les Delta Tables.

Prérequis

Avant d'exécuter les opérations DELETE ou UPDATE, vous devez disposer des autorisations Select et Update sur la table transactionnelle ou la Delta Table cible. Pour plus d'informations sur l'autorisation, consultez Autorisations MaxCompute.

Présentation des fonctionnalités

À l'instar de leur utilisation dans les bases de données traditionnelles, les fonctionnalités DELETE et UPDATE de MaxCompute permettent de supprimer ou de mettre à jour des lignes spécifiques d'une table.

Lorsque vous utilisez la fonctionnalité DELETE ou UPDATE, le système génère automatiquement un fichier Delta pour chaque opération de suppression ou de mise à jour. Ce fichier n'est pas visible par les utilisateurs et enregistre les informations relatives aux données supprimées ou mises à jour. Le mécanisme de fonctionnement est le suivant :

  • DELETE : le fichier Delta utilise les champs txnid(BIGINT) et rowid(BIGINT) pour identifier l'enregistrement du fichier de base d'une table transactionnelle qui a été supprimé, ainsi que l'opération de suppression correspondante. Un fichier de base constitue le format de stockage sous-jacent d'une table.

    Par exemple, supposons que le fichier de base de la table t1 soit f1 et que son contenu soit a, b, c, a, b. Lorsque vous exécutez la commande DELETE FROM t1 WHERE c1='a';, le système génère un fichier f1.delta distinct. Si l'identifiant txnid est t0, le contenu de f1.delta est ((0, t0), (3, t0)). Cela indique que la ligne 0 et la ligne 3 ont été supprimées lors de la transaction t0. Si vous exécutez une autre opération DELETE, le système génère un autre fichier Delta, tel que f2.delta. Ce fichier fait également référence au fichier de base original f1. Lors de l'interrogation des données, le système combine le fichier de base f1 avec tous les fichiers Delta actuels pour récupérer uniquement les enregistrements qui n'ont pas été supprimés.

  • UPDATE : une opération UPDATE est implémentée sous la forme d'une opération DELETE suivie d'une opération INSERT INTO.

Les fonctionnalités DELETE et UPDATE présentent les avantages suivants :

  • Réduction du volume de données écrites

    Auparavant, MaxCompute utilisait les opérations INSERT INTO ou INSERT OVERWRITE pour supprimer ou mettre à jour les données d'une table. Pour plus d'informations, consultez Insérer ou écraser des données (INSERT INTO | INSERT OVERWRITE). Lorsque vous deviez mettre à jour une petite quantité de données dans une table ou une partition, l'utilisation d'une opération INSERT nécessitait de lire d'abord toutes les données de la table, de mettre à jour les données via une opération SELECT, puis de réécrire l'intégralité des données dans la table avec une opération INSERT. Cette méthode était inefficace. Avec les fonctionnalités DELETE ou UPDATE, le système n'a pas besoin de réécrire l'ensemble des données, ce qui réduit considérablement le volume de données écrites.

    Remarque
    • Pour le mode de facturation au paiement à l'utilisation, les opérations d'écriture des jobs DELETE, UPDATE et INSERT OVERWRITE ne sont pas facturées. Toutefois, les jobs DELETE et UPDATE doivent lire les données des partitions pour marquer les enregistrements à supprimer ou pour écrire les enregistrements mis à jour. Ces opérations de lecture restent facturées selon le modèle de facturation au paiement à l'utilisation pour les jobs SQL. Par conséquent, les jobs DELETE et UPDATE ne réduisent pas nécessairement les coûts par rapport aux jobs INSERT OVERWRITE, même si moins de données sont écrites.

    • Pour le mode de facturation par abonnement, les opérations DELETE et UPDATE consomment moins de ressources d'écriture. Par rapport à INSERT OVERWRITE, vous pouvez exécuter davantage de jobs avec les mêmes ressources.

  • Accès direct au dernier état de la table

    Auparavant, MaxCompute utilisait des tables zipper pour les mises à jour de données par lots. Cette méthode nécessitait l'ajout de colonnes auxiliaires telles que start_date et end_date à la table afin de suivre le cycle de vie d'un enregistrement. Pour interroger le dernier état de la table, le système devait filtrer une grande quantité de données en fonction des horodatages pour trouver l'état actuel, ce qui s'avérait complexe. Avec les fonctionnalités DELETE et UPDATE, vous pouvez lire directement le dernier état de la table. Le système combine les fichiers de base et les fichiers Delta pour fournir la vue actuelle des données.

Important

L'exécution répétée des opérations DELETE et UPDATE augmente le stockage sous-jacent d'une table transactionnelle. Cela entraîne une hausse des coûts de stockage et une dégradation des performances des requêtes ultérieures. Vous devez fusionner (compacter) régulièrement les données sous-jacentes. Pour plus d'informations sur les opérations de fusion, consultez UPDATE | DELETE.

Si plusieurs jobs s'exécutent simultanément sur la même table cible, des conflits de jobs peuvent survenir. Pour plus d'informations, consultez Sémantique ACID.

Cas d'utilisation

Les fonctionnalités DELETE et UPDATE sont adaptées aux suppressions ou mises à jour aléatoires et peu fréquentes d'une petite quantité de données dans une table ou une partition. Par exemple, vous pouvez effectuer quotidiennement (T+1) des suppressions ou mises à jour par lots sur moins de 5 % des lignes d'une table ou d'une partition.

Les fonctionnalités DELETE et UPDATE ne conviennent pas aux mises à jour fréquentes, aux suppressions répétées ou aux écritures en temps réel dans une table cible.

Limites

  • Les fonctionnalités DELETE et UPDATE peuvent être utilisées uniquement sur les tables transactionnelles et les Delta Tables, sous réserve des limites suivantes :

    Remarque

    Pour plus d'informations sur les tables transactionnelles et les Delta Tables, consultez Paramètres pour Transaction Table et Delta Table.

  • La syntaxe UPDATE pour les Delta Tables ne prend pas en charge la modification des colonnes de clé primaire (PK).

Précautions

Prenez en compte les éléments suivants lorsque vous utilisez les opérations DELETE ou UPDATE pour supprimer ou mettre à jour des données dans une table ou une partition :

  • Utilisez les opérations DELETE et UPDATE pour supprimer ou mettre à jour une petite quantité de données dans une table, lorsque l'opération elle-même et les lectures ultérieures sont peu fréquentes. Après avoir effectué plusieurs opérations de suppression ou de mise à jour, fusionnez les fichiers de base et les fichiers Delta de la table afin de réduire son empreinte de stockage. Pour plus d'informations, consultez UPDATE | DELETE.

  • Si vous supprimez ou mettez à jour un grand nombre de lignes (plus de 5 %) de manière peu fréquente, mais que les opérations de lecture ultérieures sur la table sont fréquentes, utilisez INSERT OVERWRITE ou INSERT INTO. Pour plus d'informations, consultez Insérer ou écraser des données (INSERT INTO | INSERT OVERWRITE).

    Par exemple, dans un scénario métier impliquant la suppression ou la mise à jour de 10 % des données 10 fois par jour, évaluez si les coûts et la dégradation des performances de lecture ultérieure liés aux opérations DELETE et UPDATE sont inférieurs à ceux engendrés par l'utilisation de INSERT OVERWRITE ou INSERT INTO pour chaque opération. Comparez l'efficacité des deux méthodes dans votre scénario spécifique pour choisir l'option la plus adaptée.

  • La suppression de données génère des fichiers Delta, ce qui signifie que l'opération ne réduit pas immédiatement le stockage. Si vous souhaitez réduire le stockage à l'aide de l'opération DELETE, vous devez fusionner les fichiers de base et les fichiers Delta de la table. Pour plus d'informations, consultez UPDATE | DELETE.

  • MaxCompute exécute les jobs DELETE et UPDATE en tant que processus par lots. Chaque instruction consomme des ressources et engendre des frais. Vous devez supprimer ou mettre à jour les données par lots. Par exemple, si vous utilisez un script Python pour générer et soumettre de nombreux jobs de mise à jour au niveau de la ligne, où chaque instruction ne porte que sur une ou quelques lignes, chaque instruction entraîne des coûts basés sur la quantité de données d'entrée analysées par le SQL. Le coût cumulé de nombreuses instructions de ce type augmente considérablement les dépenses et réduit l'efficacité du système. Voici des exemples de commandes.

    • Méthode recommandée :

      UPDATE table1 SET col1= (SELECT value1 FROM table2 WHERE table1.id = table2.id AND table1.region = table2.region);
    • Méthode non recommandée :

      UPDATE table1 SET col1=1 WHERE id='2021063001' AND region='beijing';                 
      UPDATE table1 SET col1=2 WHERE id='2021063002' AND region='beijing';

Supprimer des données

L'opération DELETE supprime une ou plusieurs lignes répondant à des conditions spécifiées d'une table transactionnelle ou d'une Delta Table.

  • Syntaxe

    DELETE FROM <table_name> [[AS] alias] [WHERE <condition>];
  • Paramètres

    Paramètre

    Obligatoire

    Description

    table_name

    Oui

    Nom de la table transactionnelle ou de la Delta Table sur laquelle vous souhaitez exécuter l'opération DELETE.

    alias

    Non

    Alias de la table.

    where_condition

    Non

    Clause WHERE permettant de filtrer les données répondant à la condition. Pour plus d'informations sur la clause WHERE, consultez Syntaxe SELECT. Si vous n'incluez pas de clause WHERE, toutes les données de la table sont supprimées.

  • Exemples

    • Exemple 1 : créez une table non partitionnée nommée acid_delete, importez des données, puis exécutez l'opération DELETE pour supprimer les lignes répondant à une condition spécifiée. Voici les commandes d'exemple :

      -- Create a Transactional table named acid_delete.
      CREATE TABLE IF NOT EXISTS acid_delete (id BIGINT) TBLPROPERTIES ("transactional"="true");
      
      -- Insert data.
      INSERT OVERWRITE TABLE acid_delete VALUES (1), (2), (3), (2);
      
      -- View the inserted data.
      SELECT * FROM acid_delete;
      
      +------------+
      | id         |
      +------------+
      | 1          |
      | 2          |
      | 3          |
      | 2          |
      +------------+
      
      -- Delete rows where id is 2. If you run this command on the MaxCompute client (odpscmd), you must enter yes or no to confirm.
      DELETE FROM acid_delete WHERE id = 2;
      -- The following command is equivalent to the one above.
      DELETE FROM acid_delete ad WHERE ad.id = 2;
      
      -- View the result. The table now contains only data for 1 and 3.
      SELECT * FROM acid_delete;
      
      +------------+
      | id         |
      +------------+
      | 1          |
      | 3          |
      +------------+
    • Exemple 2 : créez une table partitionnée nommée acid_delete_pt, importez des données, puis exécutez l'opération DELETE pour supprimer les lignes répondant à une condition spécifiée. Voici les commandes d'exemple :

      -- Create a Transactional table named acid_delete_pt.  
      CREATE TABLE IF NOT EXISTS acid_delete_pt (id BIGINT) PARTITIONED BY (ds STRING) TBLPROPERTIES ("transactional"="true");
      
      -- Add partitions.
      ALTER TABLE acid_delete_pt ADD IF NOT EXISTS PARTITION (ds = '2019');
      ALTER TABLE acid_delete_pt ADD IF NOT EXISTS PARTITION (ds = '2018');
      
      -- Insert data.
      INSERT OVERWRITE TABLE acid_delete_pt PARTITION (ds = '2019') VALUES (1), (2), (3);
      INSERT OVERWRITE TABLE acid_delete_pt PARTITION (ds = '2018') VALUES (1), (2), (3);
      
      -- View the inserted data.
      SELECT * FROM acid_delete_pt;
      
      +------------+------------+
      | id         | ds         |
      +------------+------------+
      | 1          | 2018       |
      | 2          | 2018       |
      | 3          | 2018       |
      | 1          | 2019       |
      | 2          | 2019       |
      | 3          | 2019       |
      +------------+------------+
      
      -- Delete data where the partition is 2019 and id is 2. If you run this command on the MaxCompute client (odpscmd), you must enter yes or no to confirm.
      DELETE FROM acid_delete_pt WHERE ds = '2019' AND id = 2;
      
      -- View the result. The data where the partition is 2019 and id is 2 has been deleted.
      SELECT * FROM acid_delete_pt;
      
      +------------+------------+
      | id         | ds         |
      +------------+------------+
      | 1          | 2018       |
      | 2          | 2018       |
      | 3          | 2018       |
      | 1          | 2019       |
      | 3          | 2019       |
      +------------+------------+
    • Exemple 3 : créez une table cible nommée acid_delete_t et une table associée nommée acid_delete_s. Ensuite, supprimez les lignes répondant à une condition spécifiée via une opération de jointure. Voici les commandes d'exemple :

      -- Create a target Transactional table named acid_delete_t and an associated table named acid_delete_s. 
      CREATE TABLE IF NOT EXISTS acid_delete_t (id INT, value1 INT, value2 INT) TBLPROPERTIES ("transactional"="true");
      CREATE TABLE IF NOT EXISTS acid_delete_s (id INT, value1 INT, value2 INT);
      
      -- Insert data.
      INSERT OVERWRITE TABLE acid_delete_t VALUES (2, 20, 21), (3, 30, 31), (4, 40, 41);
      INSERT OVERWRITE TABLE acid_delete_s VALUES (1, 100, 101), (2, 200, 201), (3, 300, 301);
      
      -- Delete rows from the acid_delete_t table where the id does not match an id in the acid_delete_s table. If you run this command on the MaxCompute client (odpscmd), you must enter yes or no to confirm.
      DELETE FROM acid_delete_t WHERE NOT EXISTS (SELECT * FROM acid_delete_s WHERE acid_delete_t.id = acid_delete_s.id);
      -- The following command is equivalent to the one above.
      DELETE FROM acid_delete_t a WHERE NOT EXISTS (SELECT * FROM acid_delete_s b WHERE a.id = b.id);
      
      -- View the result. The table now contains only data for id 2 and 3.
      SELECT * FROM acid_delete_t;
      
      +------------+------------+------------+
      | id         | value1     | value2     |
      +------------+------------+------------+
      | 2          | 20         | 21         |
      | 3          | 30         | 31         |
      +------------+------------+------------+
    • Exemple 4 : créez une Delta Table nommée mf_dt, importez des données, puis exécutez l'opération DELETE pour supprimer les lignes répondant à une condition spécifiée. Voici les commandes d'exemple :

      -- Create a target Delta Table named mf_dt. 
      CREATE TABLE IF  NOT EXISTS mf_dt (pk BIGINT  NOT NULL PRIMARY KEY, 
                        val  BIGINT NOT NULL) 
                        PARTITIONED BY(dd STRING, hh STRING) 
                        tblproperties ("transactional"="true");
      
      -- Insert data.
      INSERT OVERWRITE TABLE mf_dt PARTITION (dd='01', hh='02') VALUES (1, 1), (2, 2), (3, 3);
      
      -- View the inserted data.                 
      SELECT * FROM mf_dt WHERE dd='01' AND hh='02';
      
      -- The following result is returned:
      +------------+------------+----+----+
      | pk         | val        | dd | hh |
      +------------+------------+----+----+
      | 1          | 1          | 01 | 02 |
      | 3          | 3          | 01 | 02 |
      | 2          | 2          | 01 | 02 |
      +------------+------------+----+----+
      
      -- Delete data where the partition is 01 and 02, and val is 2.
      DELETE FROM mf_dt WHERE val = 2  AND dd='01' AND hh='02';
      
      -- View the result. The table now contains only data where val is 1 and 3.
      SELECT * FROM mf_dt WHERE dd='01' AND hh='02';
      
      -- The following result is returned:
      +------------+------------+----+----+
      | pk         | val        | dd | hh |
      +------------+------------+----+----+
      | 1          | 1          | 01 | 02 |
      | 3          | 3          | 01 | 02 |
      +------------+------------+----+----+

Effacer les données de colonne

Vous pouvez utiliser la commande CLEAR COLUMN pour effacer les données des colonnes d'une table standard. Cette opération supprime du disque les données qui ne sont plus utilisées et définit les valeurs de colonne sur NULL, ce qui permet de réduire les coûts de stockage.

  • Syntaxe

    ALTER TABLE <table_name> 
      [PARTITION ( <pt_spec>[, <pt_spec>....] )] 
      CLEAR COLUMN column1[, column2, column3, ...]
      [WITHOUT TOUCH];
  • Paramètres

    Paramètre

    Description

    table_name

    Nom de la table dont vous souhaitez effacer les données de colonne.

    column1 , column2 ...

    Noms des colonnes dont vous souhaitez effacer les données.

    PARTITION

    Spécifie la partition. Si cette option n'est pas indiquée, l'opération s'applique à toutes les partitions.

    pt_spec

    Description de la partition, au format (partition_col1 = PARTITION_col_value1, PARTITION_col2 = PARTITION_col_value2, ...).

    WITHOUT TOUCH

    Si cette option est spécifiée, LastDataModifiedTime n'est pas mis à jour. Si cette option n'est pas spécifiée, LastDataModifiedTime est mis à jour.

    Remarque

    Actuellement, WITHOUT TOUCH est spécifié par défaut. Dans une version future, le comportement permettant d'effacer les données de colonne sans spécifier WITHOUT TOUCH sera pris en charge. Cela signifie que si WITHOUT TOUCH n'est pas spécifié, LastDataModifiedTime sera mis à jour.

  • Limites

    • Vous ne pouvez pas effectuer d'opération d'effacement de colonne sur des colonnes comportant une contrainte NOT NULL. Vous pouvez supprimer manuellement la contrainte NOT NULL :

      ALTER TABLE <table_name> change COLUMN <old_col_name> NULL;
    • L'effacement des données de colonne n'est pas pris en charge pour les tables ACID.

    • L'effacement des données de colonne n'est pas pris en charge pour les tables clusterisées.

    • L'effacement des données de colonne au sein de types imbriqués n'est pas pris en charge.

    • L'effacement de toutes les colonnes n'est pas pris en charge. La commande DROP TABLE produit le même effet avec de meilleures performances.

  • Précautions

    • L'opération CLEAR COLUMN ne modifie pas la propriété Archive de la table.

    • L'opération CLEAR COLUMN sur une colonne de type imbriqué peut échouer.

      Cet échec se produit si vous effectuez une opération CLEAR COLUMN sur une table contenant des types imbriqués en colonnes alors que le stockage en colonnes pour les types imbriqués est désactivé.

    • La commande CLEAR COLUMN dépend du service de stockage en ligne. La tâche peut être lente si elle doit être mise en file d'attente pendant les périodes de fort volume de jobs.

    • L'opération CLEAR COLUMN nécessite des ressources de calcul pour lire et écrire des données. Pour les utilisateurs par abonnement, cela consomme des ressources de calcul. Pour les utilisateurs au paiement à l'utilisation, cela engendre les mêmes frais qu'un job SQL. (Cette fonctionnalité est actuellement en aperçu sur invitation et est temporairement gratuite.)

  • Exemples

    • -- Create a table. 
      CREATE TABLE IF  NOT EXISTS mf_cc(key STRING, 
           value STRING, 
           a1 BIGINT , 
           a2 BIGINT , 
           a3 BIGINT , 
           a4 BIGINT)  
           PARTITIONED BY(ds STRING, hr STRING);
                       
      -- Add a partition.
      ALTER TABLE mf_cc ADD IF  NOT EXISTS PARTITION (ds='20230509', hr='1641');
      
      -- Insert data.
      INSERT INTO mf_cc PARTITION (ds='20230509', hr='1641') 
           VALUES("key","value",1,22,3,4);
           
      -- Query data.     
      SELECT * FROM mf_cc WHERE ds='20230509' AND  hr='1641';
      -- The following result is returned:
      +-----+-------+------------+------------+--------+------+---------+-----+
      | key | value | a1         | a2         | a3     | a4   | ds      | hr  |
      +-----+-------+------------+------------+--------+------+---------+-----+
      | key | value | 1          | 22         | 3      | 4    | 20230509| 1641|
      +-----+-------+------------+------------+--------+------+---------+-----+
      -- Clear column data.
      ALTER TABLE mf_cc PARTITION(ds='20230509', hr='1641') 
                        CLEAR COLUMN key,a1 
          WITHOUT TOUCH;
      -- Query data.     
      SELECT * FROM mf_cc WHERE ds='20230509' AND  hr='1641';
      -- The following result is returned. The data in the key and a1 columns has become null.
      +-----+-------+------------+------------+--------+------+---------+-----+
      | key | value | a1         | a2         | a3     | a4   | ds      | hr  |
      +-----+-------+------------+------------+--------+------+---------+-----+
      | null| value | null       | 22         | 3      | 4    | 20230509| 1641|
      +-----+-------+------------+------------+--------+------+---------+-----+
    • La figure suivante illustre l'évolution de la taille totale de stockage de la table lineitem (au format AliORC) à mesure que chaque colonne est effacée à l'aide de la commande CLEAR COLUMN. La table lineitem comporte 16 colonnes de divers types, notamment BIGINT, DECIMAL, CHAR, DATE et VARCHAR.image.png

      Comme vous pouvez le constater, après que les 16 colonnes de la table ont été séquentiellement définies sur NULL par la commande CLEAR COLUMN, l'espace de stockage total est réduit de 99,97 % (passant de 186 783 526 octets initiaux à 236 715 octets).

      Remarque
      • La quantité d'espace économisée par l'opération CLEAR COLUMN dépend du type de données et des valeurs réellement stockées dans la colonne. Par exemple, l'effacement de la colonne l_extendedprice, qui est de type DECIMAL, a permis d'économiser 24,2 % d'espace (passant de 146 538 799 octets à 111 138 117 octets), ce qui est nettement supérieur à la moyenne.

      • Lorsque toutes les colonnes sont définies sur NULL, la taille de la table est de 236 715 octets, et non de 0. En effet, la structure de fichier de la table existe toujours. Les champs NULL occupent une petite quantité d'espace de stockage, et le système doit également conserver les informations du pied de page du fichier.

Mettre à jour des données

L'opération UPDATE met à jour les valeurs d'une ou plusieurs colonnes pour les lignes d'une table transactionnelle ou d'une Delta Table.

  • Syntaxe

    -- Method 1
    UPDATE <table_name> [[AS] alias] SET <col1_name> = <value1> [, <col2_name> = <value2> ...] [WHERE <where_condition>];
    
    -- Method 2
    UPDATE <table_name> [[AS] alias] SET (<col1_name> [, <col2_name> ...]) = (<value1> [, <value2> ...]) [WHERE <where_condition>];
    
    -- Method 3
    UPDATE <table_name> [[AS] alias]
        SET <col1_name> = <value1> [, <col2_name> = <value2>, ...]
        [FROM <additional_tables>]
        [WHERE <where_condition>];
  • Paramètres

    • table_name : obligatoire. Nom de la table transactionnelle ou de la Delta Table pour l'opération UPDATE.

    • alias : facultatif. Alias de la table.

    • col1_name, col2_name : obligatoires. Noms des colonnes à modifier. Vous devez mettre à jour au moins une colonne.

    • value1, value2 : obligatoires. Nouvelles valeurs des colonnes. Vous devez mettre à jour au moins une valeur de colonne.

    • where_condition : facultatif. Clause WHERE permettant de filtrer les données. Pour plus d'informations sur la clause WHERE, consultez Syntaxe SELECT. Si vous n'incluez pas de clause WHERE, toutes les données de la table sont mises à jour.

    • additional_tables : facultatif. Clause FROM.

      L'instruction UPDATE prend en charge la clause FROM, ce qui peut simplifier l'instruction UPDATE. Le tableau suivant compare une instruction UPDATE utilisant une clause FROM à une instruction n'en utilisant pas.

      Scénario

      Exemple de code

      Sans clause FROM

      UPDATE target SET v = 
        (SELECT MIN(v) FROM src GROUP BY k WHERE target.k = src.key)
        WHERE target.k IN (SELECT k FROM src);

      Avec clause FROM

      UPDATE target SET v = b.v
        FROM (SELECT k, MIN(v) AS v FROM src GROUP BY k) b
        WHERE target.k = b.k;

      Comme le montrent les exemples de code :

      • Lorsque vous mettez à jour une ligne de la table cible en utilisant plusieurs lignes de la table source, vous devez utiliser une opération d'agrégation pour garantir l'unicité des données source, car le système ne sait pas quelle ligne source utiliser. La syntaxe n'utilisant pas de clause FROM est moins concise. La syntaxe avec une clause FROM est plus simple et plus facile à comprendre.

      • Lors d'une mise à jour par jointure, si vous souhaitez mettre à jour uniquement l'intersection des données, la syntaxe n'utilisant pas de clause FROM nécessite une condition WHERE supplémentaire et est moins concise que la syntaxe utilisant une clause FROM.

  • Exemples

    • Exemple 1 : créez une table non partitionnée nommée acid_update, importez des données, puis exécutez l'opération UPDATE pour mettre à jour les colonnes des lignes répondant à une condition spécifiée. Voici les commandes d'exemple :

      -- Create a Transactional table named acid_update.  
      CREATE TABLE IF  NOT EXISTS acid_update(id BIGINT) tblproperties ("transactional"="true");
      
      -- Insert data.
      INSERT OVERWRITE TABLE acid_update VALUES(1),(2),(3),(2);
      
      -- View the inserted data.
      SELECT * FROM acid_update; 
      
      -- The following result is returned:
      +------------+
      | id         |
      +------------+
      | 1          |
      | 2          |
      | 3          |
      | 2          |
      +------------+
      
      -- Update the id value to 4 for all rows where id is 2.
      UPDATE acid_update SET id = 4 WHERE id = 2; 
      
      -- View the update result. 2 has been updated to 4.
      SELECT * FROM acid_update; 
      
      -- The following result is returned:
      +------------+
      | id         |
      +------------+
      | 1          |
      | 3          |
      | 4          |
      | 4          |
      +------------+
    • Exemple 2 : créez une table partitionnée nommée acid_update, importez des données, puis exécutez l'opération UPDATE pour mettre à jour les colonnes des lignes répondant à une condition spécifiée. Voici les commandes d'exemple :

      -- Create a Transactional table named acid_update_pt. 
      CREATE TABLE IF  NOT EXISTS acid_update_pt(id BIGINT) PARTITIONED BY(ds STRING) tblproperties ("transactional"="true");
      
      -- Add a partition.
      ALTER TABLE acid_update_pt ADD IF  NOT EXISTS PARTITION (ds= '2019');
      
      -- Insert data.
      INSERT OVERWRITE TABLE acid_update_pt PARTITION (ds='2019') VALUES(1),(2),(3);
      
      -- View the inserted data.
      SELECT * FROM acid_update_pt WHERE ds = '2019'; 
      
      -- The following result is returned:
      +------------+------------+
      | id         | ds         |
      +------------+------------+
      | 1          | 2019       |
      | 2          | 2019       |
      | 3          | 2019       |
      +------------+------------+
      
      -- Update a column in a specified row. Set the id value to 4 for all rows where the partition is 2019 and id is 2.
      UPDATE acid_update_pt SET id = 4 WHERE ds = '2019' AND id = 2; 
      
      -- View the update result. 2 has been updated to 4.
      SELECT * FROM acid_update_pt WHERE ds = '2019';
      
      -- The following result is returned:
      +------------+------------+
      | id         | ds         |
      +------------+------------+
      | 4          | 2019       |
      | 1          | 2019       |
      | 3          | 2019       |
      +------------+------------+
    • Exemple 3 : créez une table cible nommée acid_update_t et une table associée nommée acid_update_s pour mettre à jour plusieurs valeurs de colonne simultanément. Voici les commandes d'exemple :

      -- Create a target Transactional table to be updated, named acid_update_t, and an associated table named acid_update_s.
      CREATE TABLE IF  NOT EXISTS acid_update_t(id INT,value1 INT,value2 INT) tblproperties ("transactional"="true");
      CREATE TABLE IF  NOT EXISTS acid_update_s(id INT,value1 INT,value2 INT); 
      
      -- Insert data.
      INSERT OVERWRITE TABLE acid_update_t VALUES(2,20,21),(3,30,31),(4,40,41);
      INSERT OVERWRITE TABLE acid_update_s VALUES(1,100,101),(2,200,201),(3,300,301);
      
      -- Method 1: Update with constants.
      UPDATE acid_update_t SET (value1, value2) = (60,61);
      -- Query the result data in the target table for Method 1.
      SELECT * FROM acid_update_t;
      
      -- The following result is returned:
      +------------+------------+------------+
      | id         | value1     | value2     |
      +------------+------------+------------+
      | 2          | 60         | 61         |
      | 3          | 60         | 61         |
      | 4          | 60         | 61         |
      +------------+------------+------------+
      
      -- Method 2: Join update. The rule is a left join from acid_update_t to acid_update_s.
      UPDATE acid_update_t SET (value1, value2) = (SELECT value1, value2 FROM acid_update_s WHERE acid_update_t.id = acid_update_s.id);
      -- Query the result data in the target table for Method 2.
      SELECT * FROM acid_update_t;
      
      -- The following result is returned:
      +------------+------------+------------+
      | id         | value1     | value2     |
      +------------+------------+------------+
      | 2          | 200        | 201        |
      | 3          | 300        | 301        |
      | 4          | NULL       | NULL       |
      +------------+------------+------------+
      
      -- Method 3 (update based on the result of Method 2): Join update. The rule is to add a filter condition to update only the intersection.
      UPDATE acid_update_t SET (value1, value2) = (SELECT value1, value2 FROM acid_update_s WHERE acid_update_t.id = acid_update_s.id) WHERE acid_update_t.id IN (SELECT id FROM acid_update_s);
      -- Query the result data in the target table for Method 3.
      SELECT * FROM acid_update_t;
      
      -- The following result is returned:
      +------------+------------+------------+
      | id         | value1     | value2     |
      +------------+------------+------------+
      | 2          | 200        | 201        |
      | 3          | 300        | 301        |
      | 4          | NULL       | NULL       |
      +------------+------------+------------+
      
      -- Method 4 (update based on the result of Method 3): Join update with aggregate results.
      UPDATE acid_update_t SET (id, value1, value2) = (SELECT id, MAX(value1),MAX(value2) FROM acid_update_s WHERE acid_update_t.id = acid_update_s.id GROUP BY acid_update_s.id) WHERE acid_update_t.id IN (SELECT id FROM acid_update_s);
      -- Query the result data in the target table for Method 4.
      SELECT * FROM acid_update_t;
      
      -- The following result is returned:
      +------------+------------+------------+
      | id         | value1     | value2     |
      +------------+------------+------------+
      | 2          | 200        | 201        |
      | 3          | 300        | 301        |
      | 4          | NULL       | NULL       |
      +------------+------------+------------+
    • Exemple 4 : requête de jointure simple impliquant deux tables. Voici les commandes d'exemple :

      -- Create a target table for update, acid_update_t, and an associated table, acid_update_s. 
      CREATE TABLE IF  NOT EXISTS acid_update_t(id BIGINT,value1 BIGINT,value2 BIGINT) tblproperties ("transactional"="true");
      CREATE TABLE IF  NOT EXISTS acid_update_s(id BIGINT,value1 BIGINT,value2 BIGINT);
      
      -- Insert data.
      INSERT OVERWRITE TABLE acid_update_t VALUES(2,20,21),(3,30,31),(4,40,41);
      INSERT OVERWRITE TABLE acid_update_s VALUES(1,100,101),(2,200,201),(3,300,301);
      
      -- Query data from the acid_update_t table.
      SELECT * FROM acid_update_t;
      -- The following result is returned:
      +------------+------------+------------+
      | id         | value1     | value2     |
      +------------+------------+------------+
      | 2          | 20         | 21         |
      | 3          | 30         | 31         |
      | 4          | 40         | 41         |
      +------------+------------+------------+
      
      -- Query data from the acid_update_s table.
      SELECT * FROM acid_update_s;
      -- The following result is returned:
      +------------+------------+------------+
      | id         | value1     | value2     |
      +------------+------------+------------+
      | 1          | 100        | 101        |
      | 2          | 200        | 201        |
      | 3          | 300        | 301        |
      +------------+------------+------------+
      
      -- Join update. Add a filter condition to the target table to update only the intersection.
      UPDATE acid_update_t SET value1 = b.value1, value2 = b.value2
      FROM acid_update_s b WHERE acid_update_t.id = b.id;
      -- The following command is equivalent to the one above.
      UPDATE acid_update_t a SET a.value1 = b.value1, a.value2 = b.value2 
      FROM acid_update_s b WHERE a.id = b.id;
      
      -- View the update result. 20 is updated to 200, 21 to 201, 30 to 300, and 31 to 301.
      SELECT * FROM acid_update_t;
      -- The following result is returned:
      +------------+------------+------------+
      | id         | value1     | value2     |
      +------------+------------+------------+
      | 4          | 40         | 41         |
      | 2          | 200        | 201        |
      | 3          | 300        | 301        |
      +------------+------------+------------+                          
    • Exemple 5 : requête de jointure complexe impliquant plusieurs tables. Voici les commandes d'exemple :

      -- Create a target table for update, acid_update_t, and an associated table, acid_update_s. 
      CREATE TABLE IF  NOT EXISTS acid_update_t(id BIGINT,value1 BIGINT,value2 BIGINT) tblproperties ("transactional"="true");
      CREATE TABLE IF  NOT EXISTS acid_update_s(id BIGINT,value1 BIGINT,value2 BIGINT);
      CREATE TABLE IF  NOT EXISTS acid_update_m(id BIGINT,value1 BIGINT,value2 BIGINT);
      
      -- Insert data.
      INSERT OVERWRITE TABLE acid_update_t VALUES(2,20,21),(3,30,31),(4,40,41),(5,50,51);
      INSERT OVERWRITE TABLE acid_update_s VALUES (1,100,101),(2,200,201),(3,300,301),(4,400,401),(5,500,501);
      INSERT OVERWRITE TABLE acid_update_m VALUES(3,30,101),(4,400,201),(5,300,301);
      
      -- Query data from the acid_update_t table.
      SELECT * FROM acid_update_t;
      -- The following result is returned:
      +------------+------------+------------+
      | id         | value1     | value2     |
      +------------+------------+------------+
      | 2          | 20         | 21         |
      | 3          | 30         | 31         |
      | 4          | 40         | 41         |
      | 5          | 50         | 51         |
      +------------+------------+------------+
      
      -- Query data from the acid_update_s table.
      SELECT * FROM acid_update_s;
      -- The following result is returned:
      +------------+------------+------------+
      | id         | value1     | value2     |
      +------------+------------+------------+
      | 1          | 100        | 101        |
      | 2          | 200        | 201        |
      | 3          | 300        | 301        |
      | 4          | 400        | 401        |
      | 5          | 500        | 501        |
      +------------+------------+------------+
      
      -- Query data from the acid_update_m table.
      SELECT * FROM acid_update_m;
      -- The following result is returned:
      +------------+------------+------------+
      | id         | value1     | value2     |
      +------------+------------+------------+
      | 3          | 30         | 101        |
      | 4          | 400        | 201        |
      | 5          | 300        | 301        |
      +------------+------------+------------+
      
      -- Join update, and filter both the source and target tables in the WHERE clause.
      UPDATE acid_update_t 
      SET value1 = acid_update_s.value1, value2 = acid_update_s.value2 
      FROM acid_update_s 
      WHERE acid_update_t.id = acid_update_s.id 
      AND acid_update_s.id > 2 
      AND acid_update_t.value1 NOT IN 
      (SELECT value1 FROM acid_update_m WHERE id = acid_update_t.id) 
      AND acid_update_s.value1 NOT IN 
      (SELECT value1 FROM acid_update_m WHERE id = acid_update_s.id);
      
      -- View the update result. Only the data in the acid_update_t table with id 5 meets the condition. The corresponding value1 is updated to 500, and value2 is updated to 501.
      SELECT * FROM acid_update_t;
      -- The following result is returned:
      +------------+------------+------------+
      | id         | value1     | value2     |
      +------------+------------+------------+
      | 5          | 500        | 501        |
      | 2          | 20         | 21         |
      | 3          | 30         | 31         |
      | 4          | 40         | 41         |
      +------------+------------+------------+
    • Exemple 6 : la commande suivante illustre comment créer une Delta Table nommée mf_dt, importer des données et exécuter une opération UPDATE pour supprimer les lignes répondant à une condition spécifiée :

      -- Create a target Delta Table named mf_dt.
      CREATE TABLE IF  NOT EXISTS mf_dt (pk BIGINT  NOT NULL PRIMARY KEY, 
                        val  BIGINT NOT NULL) 
                        PARTITIONED BY(dd STRING, hh STRING) 
                        tblproperties ("transactional"="true");
      
      -- Insert data.
      INSERT OVERWRITE TABLE mf_dt PARTITION (dd='01', hh='02') 
                       VALUES (1, 1), (2, 2), (3, 3);
      
      -- View the inserted data.                 
      SELECT * FROM mf_dt WHERE dd='01' AND hh='02';
      -- The following result is returned:
      +------------+------------+----+----+
      | pk         | val        | dd | hh |
      +------------+------------+----+----+
      | 1          | 1          | 01 | 02 |
      | 3          | 3          | 01 | 02 |
      | 2          | 2          | 01 | 02 |
      +------------+------------+----+----+
      
      -- Update a column in a specified row. Set the val value to 30 for all rows where the partition is 01 and 02, and pk is 3.
      -- Method 1
      UPDATE mf_dt SET val = 30 WHERE pk = 3 AND dd='01' AND hh='02';
      
      -- Method 2
      UPDATE mf_dt SET val = delta.val 
                    FROM (SELECT pk, val FROM VALUES (3, 30) t (pk, val)) delta 
                    WHERE delta.pk = mf_dt.pk AND mf_dt.dd='01' AND mf_dt.hh='02';
      
      -- View the update result.
      SELECT * FROM mf_dt WHERE dd='01' AND hh='02';
      -- The following result is returned. The val value for the row with pk=3 is updated to 30.
      +------------+------------+----+----+
      | pk         | val        | dd | hh |
      +------------+------------+----+----+
      | 1          | 1          | 01 | 02 |
      | 3          | 30         | 01 | 02 |
      | 2          | 2          | 01 | 02 |
      +------------+------------+----+----+

Fusionner les fichiers de table transactionnelle

Le stockage physique sous-jacent d'une table transactionnelle est composé de fichiers de base et de fichiers Delta, qui ne sont pas directement lisibles. Lorsque vous exécutez une opération UPDATE ou DELETE sur une table transactionnelle, les fichiers de base ne sont pas modifiés. À la place, des fichiers Delta sont ajoutés. Cela signifie que plus vous effectuez de mises à jour ou de suppressions, plus la table occupe d'espace de stockage. L'accumulation de nombreux fichiers Delta peut augmenter le stockage et les coûts des requêtes ultérieures.

L'exécution de plusieurs opérations UPDATE ou DELETE sur la même table ou partition génère de nombreux fichiers Delta. Lorsque le système lit les données, il doit charger ces fichiers Delta pour déterminer quelles lignes ont été mises à jour ou supprimées. La présence de nombreux fichiers Delta peut dégrader les performances de lecture des données. Dans ce cas, vous pouvez fusionner les fichiers de base et les fichiers Delta pour réduire le stockage et améliorer les performances de lecture des données.

  • Syntaxe

    ALTER TABLE <table_name> [PARTITION (<partition_key> = '<partition_value>' [, ...])] compact {minor|major};
  • Paramètres

    Paramètre

    Obligatoire

    Description

    table_name

    Oui

    Nom de la table transactionnelle dont vous souhaitez fusionner les fichiers.

    partition_key

    Non

    Si la table transactionnelle est une table partitionnée, spécifiez le nom de la colonne de clé de partition.

    partition_value

    Non

    Si la table transactionnelle est une table partitionnée, spécifiez la valeur de la colonne de clé de partition.

    major|minor

    Oui

    Vous devez en choisir un. Les différences sont les suivantes :

    minor : fusionne uniquement les fichiers de base et tous leurs fichiers Delta sous-jacents, en éliminant les fichiers Delta.

    major : non seulement fusionne les fichiers de base et tous leurs fichiers Delta sous-jacents pour éliminer les fichiers Delta, mais fusionne également les petits fichiers au sein des fichiers de base correspondants de la table. Si un fichier de base est petit (inférieur à 32 Mo) ou si des fichiers Delta existent, cela équivaut à exécuter à nouveau une opération INSERT OVERWRITE sur la table. Cependant, si le fichier de base est suffisamment grand (supérieur ou égal à 32 Mo) et qu'aucun fichier Delta n'existe, il ne sera pas réécrit.

  • Précautions

    Les petits fichiers fusionnés par l'opération compact sont supprimés après un jour. Si vous utilisez la fonctionnalité sauvegarde locale pour restaurer un historique dépendant de ces petits fichiers, la récupération échouera car les fichiers seront manquants.

  • Exemples

    • Exemple 1 : fusionner les fichiers de la table transactionnelle acid_delete. Voici la commande d'exemple :

      ALTER TABLE acid_delete compact minor; 

      Le résultat suivant est renvoyé :

      Summary:
      Nothing found to merge, set odps.merge.cross.paths=true if cross path merge is permitted.
      OK
    • Exemple 2 : fusionner les fichiers de la table transactionnelle acid_update_pt. Voici la commande d'exemple :

      ALTER TABLE acid_update_pt PARTITION (ds = '2019') compact major; 

      Le résultat suivant est renvoyé :

      Summary:
      table name: acid_update_pt /ds=2019  instance count: 2  run time: 6
        before merge, file count:        8  file size: 2613  file physical size: 7839
         after merge, file count:        2  file size: 679  file physical size: 2037
      
      OK

FAQ

  • Problème 1 :

    • Description du problème : lors de l'exécution d'une instruction UPDATE, l'erreur ODPS-0010000:System internal error - fuxi job failed, caused by: Data Set should contain exactly one row est signalée.

    • Cause : les lignes à mettre à jour ne correspondent pas bijectivement aux données du résultat de la sous-requête. Le système ne peut pas déterminer quelle ligne mettre à jour. Voici une commande d'exemple :

      UPDATE store SET (s_county, s_manager) = (SELECT d_country, d_manager FROM store_delta sd WHERE sd.s_store_sk = store.s_store_sk) WHERE s_store_sk IN (SELECT s_store_sk FROM store_delta);

      La sous-requête SELECT d_country, d_manager FROM store_delta sd WHERE sd.s_store_sk = store.s_store_sk sert à effectuer une jointure avec store_delta, et les données de store_delta sont utilisées pour mettre à jour store. Supposons que la colonne s_store_sk de la table store contienne trois lignes de données : [1, 2, 3]. Si la colonne s_store_sk de la table store_delta comporte deux lignes de données, [1, 1], aucune correspondance bijective n'existe et l'exécution échoue.

    • Solution : assurez-vous que les lignes à mettre à jour correspondent bijectivement aux données du résultat de la sous-requête.

  • Problème 2 :

    • Description du problème : lors de l'exécution de la commande compact dans DataWorks DataStudio, l'erreur ODPS-0130161:[1,39] Parse exception - invalid token 'minor', expect one of 'StringLiteral','DoubleQuoteStringLiteral' est signalée.

    • Cause : la version du client MaxCompute dans le groupe de ressources exclusives pour DataWorks ne prend pas en charge la commande compact.

    • Solution : contactez l'équipe d'assistance technique via le groupe DingTalk DataWorks pour mettre à niveau la version du client MaxCompute dans le groupe de ressources exclusives.