Tous les produits
Search
Centre de documentation

MaxCompute:Cas de diagnostic avec LogView

Dernière mise à jour :Aug 21, 2026

Dans la plupart des cas, les entreprises ont besoin que les résultats des tâches soient générés plus tôt que prévu. Cela leur permet de prendre des décisions de développement commercial dès que possible sur la base de ces résultats. Dans ce contexte, les développeurs de tâches doivent surveiller l'état des tâches afin d'identifier et d'optimiser celles qui s'exécutent lentement. Vous pouvez utiliser LogView de MaxCompute pour diagnostiquer les tâches lentes. Cette rubrique présente les causes des ralentissements des tâches ainsi que les solutions associées. Elle explique également comment consulter les informations relatives aux tâches dont l'exécution est lente.

Diagnostiquer une tâche en échec

Lorsqu'une tâche échoue, vous pouvez afficher les informations d'erreur dans l'onglet result de LogView. Pour une tâche ayant échoué, LogView s'ouvre par défaut sur l'onglet result.

Causes possibles :

  • La syntaxe SQL est incorrecte. Dans ce cas, aucun graphe orienté acyclique (DAG) ni aucune tâche Fuxi n'existe, car la tâche n'a pas été soumise au cluster de calcul pour exécution.

  • Erreurs dans une fonction définie par l'utilisateur (UDF). Vous pouvez consulter le DAG dans l'onglet job details pour identifier la UDF problématique et vérifier les messages d'erreur dans StdOut ou StdError.

  • D'autres erreurs se produisent. Pour plus d'informations sur les autres types d'erreurs, reportez-vous à Présentation des codes d'erreur.

Diagnostiquer une tâche lente

Étape de compilation

Une tâche en cours de compilation possède un LogView, mais aucun plan d'exécution n'est encore disponible. Cette étape comprend plusieurs sous-étapes, telles que la planification, l'optimisation, la génération du plan d'exécution physique et la réplication des données entre clusters. L'onglet SubStatusHistory répertorie le code d'état (Code), la description (Description), l'heure de début et la latence pour chaque sous-étape. Un problème courant lors de la compilation est le blocage d'une tâche, c'est-à-dire qu'elle reste dans une sous-étape pendant une période prolongée. Les sections suivantes décrivent les causes possibles et les solutions pour les tâches bloquées à chaque sous-étape.

  • Planification

    Description du problème : Le sous-statut de la tâche est Waiting for cluster resource. La tâche est en attente de compilation.

    Cause : Les ressources du cluster de calcul sont insuffisantes.

    Solution : Vérifiez l'état du cluster de calcul et les ressources requises. Si vous utilisez un cluster par abonnement, vous pouvez augmenter les ressources (scale out).

  • Optimisation

    Description du problème : Le sous-statut de la tâche est SQLTask is optimizing query. L'optimiseur est en train d'optimiser le plan d'exécution.

    Cause : Le plan d'exécution est complexe. L'optimiseur nécessite beaucoup de temps pour optimiser le plan d'exécution.

    Solution : Attendez que l'optimiseur termine l'optimisation. Ce processus prend généralement moins de 10 minutes.

  • Génération d'un plan d'exécution

    Description du problème : Le sous-statut de la tâche est SQLTask is generating execution plan.

    Cause 1 : Lecture d'un nombre excessif de partitions de données.

    Solution : Optimisez les instructions SQL pour réduire le nombre de partitions. Par exemple, vous pouvez effectuer une élimination des partitions (partition pruning), filtrer les partitions dont les données n'ont pas besoin d'être lues et diviser les grandes tâches en petites tâches. Pour savoir comment déterminer si l'élimination des partitions est effective dans les instructions SQL et connaître les scénarios courants d'échec de cette opération, reportez-vous à Vérifier l'efficacité de l'élimination des partitions.

    Cause 2 : Génération excessive de petits fichiers. Les petits fichiers sont générés dans les scénarios suivants :

    1. Une opération incorrecte est effectuée lors de l'utilisation des commandes Tunnel pour télécharger des données. Par exemple, une nouvelle upload session est créée à chaque téléchargement d'enregistrement de données. Pour plus d'informations, reportez-vous à FAQ sur les commandes Tunnel.

    2. Lorsque vous exécutez une opération insert into sur une table partitionnée, un nouveau fichier est généré dans le répertoire partition.

    Solutions

    1. Utilisez l'interface TunnelBufferedWriter pour télécharger les données de manière plus efficace. Cela évite la génération excessive de petits fichiers.

    2. Fusionnez manuellement les petits fichiers. Pour plus d'informations, reportez-vous à Fusionner les petits fichiers.

    Remarque

    Si le nombre de petits fichiers dépasse 10 000, vous pouvez activer la fusion automatique des petits fichiers. Le système fusionne automatiquement les petits fichiers chaque jour. Toutefois, si le système ne parvient pas à fusionner les petits fichiers dans des scénarios particuliers, vous devez les fusionner manuellement.

  • Réplication des données entre clusters

    Symptôme : La liste des sous-statuts affiche plusieurs instances de Task rerun, et l'onglet Result affiche le message d'erreur FAILED: ODPS-0110141:Data version exception. La tâche peut sembler avoir échoué, mais elle est toujours en cours d'exécution, ce qui indique qu'elle réplique des données entre clusters.

    Cause 1 : Des données sont migrées entre clusters pour le projet. Dans ce cas, un grand nombre de tâches qui répliquent des données entre clusters s'exécutent durant les un ou deux premiers jours suivant la fin de la migration.

    Solution : Attendez que la réplication des données entre clusters soit terminée comme prévu.

    Cause 2 : Des données sont migrées entre clusters pour le projet. Cependant, les partitions ne sont pas filtrées comme prévu. Par conséquent, d'anciennes données sont lues à partir de partitions spécifiques.

    Solution : Filtrez les partitions contenant les anciennes données.

Étape d'exécution

La page job details de LogView affiche un plan d'exécution incomplet et l'état de la tâche reste Running. Pendant l'étape d'exécution, une tâche peut être bloquée ou s'exécuter plus longtemps que prévu en raison d'attentes de ressources, d'une asymétrie des données (data skew), d'une exécution inefficace des UDF ou d'une expansion des données. Les sections suivantes décrivent les symptômes et les solutions pour chaque scénario.

  • Attente de ressources

    Symptôme : Les instances sont à l'état Ready, ou certaines sont en cours d'exécution (Running) tandis que d'autres sont prêtes (Ready). Notez que si une instance est Ready mais possède un historique Debug, elle peut être en cours de nouvelle tentative après un échec, et non en attente de ressources. Dans la liste des instances Fuxi, vous pouvez filtrer par statut à l'aide de SmartFilter. La colonne Status affiche l'état actuel de chaque instance.

    Solution :

    1. Déterminez si la mise en file d'attente est normale. Vous pouvez vérifier la position de la tâche dans la file d'attente en consultant la valeur Queue Length dans le panneau Basic Info situé à gauche de LogView. Vous pouvez également vérifier l'utilisation des ressources du groupe de quotas correspondant dans la console MaxCompute. Dans le volet de navigation de gauche de la console MaxCompute, sélectionnez Project Management > Quota Management > Resource Consumption pour afficher les graphiques de tendance des métriques telles que CPU Resource pour le groupe de quotas cible. Si l'utilisation d'une ressource est proche ou supérieure à son quota, le groupe de quotas connaît une pénurie de ressources et la mise en file d'attente des tâches est normale. L'ordre de planification dépend non seulement de l'heure de soumission et de la priorité, mais aussi de la disponibilité des ressources mémoire ou CPU requises.

    2. Consultez les tâches qui utilisent le groupe de quotas.

      Des tâches volumineuses à faible priorité peuvent avoir été soumises, ou plusieurs petites tâches peuvent avoir été soumises simultanément. Ces tâches occupent un grand nombre de ressources. Vous pouvez contacter le propriétaire des tâches pour les arrêter et libérer les ressources qu'elles occupent.

    3. Modifiez le groupe de quotas de la tâche pour utiliser celui d'un autre projet.

    4. Augmentez les ressources (scale out). Cette solution convient uniquement aux utilisateurs qui disposent de ressources par abonnement.

  • Asymétrie des données (Data skew)

    Symptôme : La plupart des instances d'une tâche sont terminées, mais quelques instances « longue traîne » (long-tail) sont toujours en cours d'exécution. Ces instances s'exécutent lentement, probablement parce qu'elles traitent une quantité de données plus importante. Dans SmartFilter, vous pouvez vérifier le compteur Long-Tails et comparer la durée de chaque instance dans la colonne Latency.

    Solution : Pour plus d'informations sur les causes courantes de l'asymétrie des données et les méthodes d'optimisation associées, reportez-vous à Optimisation de l'asymétrie des données.

  • Exécution inefficace des UDF

    Dans cette rubrique, les UDF désignent diverses extensions définies par l'utilisateur, notamment les fonctions scalaires définies par l'utilisateur (UDF), les fonctions d'agrégation définies par l'utilisateur (UDAF), les fonctions tabulaires définies par l'utilisateur (UDTF), les jointures définies par l'utilisateur (UDJ) et les types définis par l'utilisateur (UDT).

    Description : L'efficacité d'exécution d'une tâche est faible et la tâche inclut des UDF. Le message d'erreur suivant, indiquant un délai d'expiration de l'exécution de la UDF, peut apparaître : Fuxi job failed - WorkerRestart errCode:252,errMsg:kInstanceMonitorTimeout, usually caused by bad udf performance.

    Dépannage : Lorsqu'une tâche échoue, vous pouvez rapidement déterminer si elle contient une UDF en examinant le DAG dans l'onglet job details de LogView. Dans le DAG, une tâche ayant échoué est colorée en rouge, et une étiquette fx telle que ["JAVA"] sur le nœud indique le langage de la UDF. Par exemple, vous pouvez constater que la tâche ayant échoué R4_3 contient une UDF écrite en Java. Double-cliquez sur R4_3 pour ouvrir la vue Operator, qui répertorie toutes les UDF de cette tâche. La vue Operator affiche la chaîne d'opérateurs de haut en bas, avec une liste de toutes les UDF référencées en bas. De plus, le journal StdOut de la tâche affiche le nombre d'enregistrements d'entrée, le nombre d'enregistrements de sortie et le temps de traitement de la UDF. Ces données vous aident à identifier les problèmes de performance. En général, une valeur Speed(records/s) de plusieurs centaines de milliers ou de millions est normale. Si elle chute à quelques dizaines de milliers, un problème de performance est probable. Le journal affiche un résumé du traitement de la UDF et un tableau statistique avec OutputCount, InnerTime et Speed(records/s) pour chaque opérateur (CursorId).

    Solution : En cas de problème de performance, vous pouvez utiliser la méthode suivante pour dépanner et optimiser les performances.

    1. Vérifiez si une erreur se produit dans la UDF.

      Dans certains cas, le problème de performance est causé par une valeur de données spécifique. Par exemple, une boucle infinie se produit lorsqu'une valeur particulière apparaît. MaxCompute Studio vous permet de télécharger des exemples de données spécifiques d'une table et de les utiliser sur votre machine locale pour le dépannage. Pour plus d'informations, reportez-vous aux sections UDF Java et UDF Python du manuel de développement MaxCompute Studio.

    2. Vérifiez si le nom de la UDF est identique à celui d'une fonction intégrée.

      Une fonction intégrée peut être écrasée par une UDF portant le même nom. Si une fonction semble être une fonction intégrée, vous devez déterminer si une UDF portant le même nom peut écraser la fonction intégrée.

    3. Remplacez la UDF par une fonction intégrée.

      Si des fonctions intégrées offrant des fonctionnalités similaires existent, nous vous recommandons de ne pas utiliser de UDF. Les fonctions intégrées sont vérifiées et utilisées de manière plus efficace. De plus, les optimiseurs effectuent des tests en boîte blanche sur les fonctions intégrées, permettant ainsi davantage d'optimisations. Pour plus d'informations sur l'utilisation des fonctions intégrées, reportez-vous à Fonctions intégrées.

    4. Remplacez les UDF spécifiques par des fonctions intégrées offrant des fonctionnalités similaires, et conservez uniquement les UDF qui ne peuvent pas être implémentées à l'aide de fonctions intégrées.

    5. Optimisez la méthode evaluate des UDF.

      N'utilisez la méthode evaluate que pour les opérations nécessaires liées aux paramètres. Effectuez à l'avance les opérations d'initialisation ou les calculs répétitifs, car la méthode evaluate est exécutée de manière répétée.

    6. Estimez la durée nécessaire à l'exécution d'une UDF.

      Simulez la quantité de données traitée par une instance sur votre machine locale pour tester la durée nécessaire à l'exécution d'une UDF. Ensuite, optimisez l'implémentation de la UDF. Par défaut, la durée maximale d'exécution d'une UDF est de 30 minutes. Une UDF doit renvoyer des données dans un délai de 30 minutes ou utiliser context.progress() pour envoyer des signaux de maintien (heartbeats). Si la durée estimée nécessaire à l'exécution d'une UDF dépasse 30 minutes, vous pouvez configurer un paramètre pour spécifier le délai d'expiration de la UDF.

      Default value: 1800. Unit: seconds. Valid values: 1 to 3600.
      -- Specify the timeout period of a UDF. Unit: seconds. Default value: 600.
      -- You can manually adjust the timeout period of the UDF in the range of [0,3600].
    7. Modifiez les paramètres de mémoire.

      La faible efficacité des UDF n'est pas nécessairement due à la complexité computationnelle. La complexité de stockage peut également affecter l'efficacité des UDF. Exemples :

      • Un dépassement de mémoire (memory overflow) se produit si une UDF effectue des calculs en mémoire ou trie une grande quantité de données.

      • Une mémoire insuffisante entraîne une fréquence élevée de garbage collection (GC).

      Vous pouvez modifier les paramètres de mémoire pour gérer temporairement les problèmes précédents. L'optimisation spécifique doit être effectuée en fonction de vos besoins métier. Exemple :

      set odps.sql.udf.jvm.memory=
      -- Specify the maximum memory size that can be used for the JVM heap of a UDF. Default value: 1024. Unit: MB.
      -- You can change the value of the odps.sql.udf.jvm.memory parameter in the range of [256,12288].
      Remarque

      Si une UDF est utilisée, l'élimination des partitions peut devenir invalide. L'annotation UdfProperty est prise en charge à partir de MaxCompute V2.0. Lorsque vous définissez une UDF, vous pouvez utiliser l'annotation pour indiquer au compilateur que la UDF est déterministe. Exemple de code :

      @com.aliyun.odps.udf.annotation.UdfProperty(isDeterministic = true)
      public class AnnotatedUdf extends com.aliyun.odps.udf.UDF {
          public String evaluate(String x) {
              return x;
          }
      }

      Si vous réécrivez l'instruction SQL pour une UDF, vous pouvez utiliser la UDF dans le filtrage des partitions.

      -- SQL statement before rewriting
      SELECT * FROM t WHERE pt = udf('foo');  -- pt indicates a partition key column of t.
      -- SQL statement after rewriting
      SELECT * FROM t WHERE pt = (SELECT udf('foo')); --pt indicates a partition key column of t.
  • Expansion des données (Data bloat)

    Symptôme : Les données de sortie d'une tâche sont beaucoup plus volumineuses que ses données d'entrée. Par exemple, si 1 Go de données devient 1 To après traitement, les performances d'une instance gérant 1 To de données seront fortement dégradées. Une fois la tâche terminée, les champs I/O Records de la tâche affichent les volumes de données d'entrée et de sortie. Si une tâche est bloquée à l'étape Join, sélectionnez quelques instances Running à l'aide de SmartFilter et vérifiez leurs journaux StdOut en cliquant sur l'icône StdOut. Si le journal StdOut affiche continuellement des enregistrements Merge join cursor et que la valeur OutputRowCount augmente constamment, cela indique une expansion sévère des données. Vous devez vérifier si la condition JOIN et la clé de jointure sont raisonnables.

    Solution :

    • Vérifiez les problèmes suivants dans le code : la condition JOIN est-elle correcte ? La condition JOIN est-elle écrite sous forme de produit cartésien ? La UDTF fonctionne-t-elle correctement ? Une quantité excessive de données de sortie est-elle générée ?

    • Vérifiez si l'expansion des données est causée par l'agrégation.

      La plupart des agrégateurs effectuent une agrégation récursive. Lorsqu'un agrégateur agrège des données, il fusionne d'abord les résultats intermédiaires. Le volume des données de résultat intermédiaire n'est pas important et la complexité de calcul de la plupart des agrégateurs est faible. L'agrégation peut être rapide même si le volume de données est important. Dans la plupart des cas, l'expansion des données ne se produit pas lors de l'agrégation. Cependant, si vous effectuez une agrégation dans les scénarios suivants, une expansion des données peut se produire :

      • Activez l'agrégation dans l'instruction SELECT pour effectuer l'opération DISTINCT sur différentes dimensions. Les données s'étendent à chaque exécution de l'opération DISTINCT.

      • Si vous utilisez l'instruction GROUPING SETS ou CUBE | ROLLUP, la taille des données de résultat intermédiaire peut être multipliée par rapport à la taille des données d'origine. Cependant, si vous utilisez une instruction spécifique telle que COLLECT_LIST ou MEDIAN, vous devez conserver toutes les données de résultat intermédiaire. Cela peut causer certains problèmes.

    • Évitez l'expansion des données due aux opérations JOIN.

      Par exemple, vous souhaitez joindre deux tables. La table de gauche contient une grande quantité de données démographiques. Cependant, l'efficacité du traitement est élevée grâce au parallélisme élevé des instances MaxCompute. La table de droite est une table de dimension qui enregistre des informations sur chaque genre, telles que les mauvaises habitudes possibles de chaque genre. La table de dimension ne contient que deux genres, mais des centaines de lignes correspondent à chaque genre. Si vous joignez les tables par genre, les données de la table de gauche peuvent être multipliées par des centaines. Pour éviter l'expansion des données, vous pouvez agréger les lignes de données de la table de droite en deux lignes avant de joindre les tables.

    • Vérifiez si l'expansion des données est causée par l'instruction GROUPING SET. Lors de l'exécution de l'instruction GROUPING SET, les données sont étendues et les données de sortie sont multipliées par rapport au nombre de groupes. Le plan d'exécution actuel ne peut pas s'adapter à l'instruction GROUPING SET ni modifier le degré de parallélisme des tâches en aval. Vous pouvez configurer manuellement le degré de parallélisme des tâches en aval. Exemples d'instructions :

      set odps.stage.reducer.num = xxx; 
      set odps.stage.joiner.num = xxx;

Étape de terminaison

La plupart des tâches SQL s'arrêtent une fois la tâche Fuxi terminée. Cependant, il arrive que l'état de la tâche reste Running même après la fin de la tâche Fuxi. Dans LogView, la page Job Details à droite affiche toutes les étapes de la tâche Fuxi comme Terminated, mais l'Status de la tâche dans le panneau de gauche est toujours Running, et la barre de Progress affiche 0 %. Cela peut se produire pour deux raisons :

  1. La tâche SQL inclut plusieurs tâches Fuxi. Par exemple, des sous-requêtes sont exécutées à plusieurs étapes, ou des tâches qui fusionnent automatiquement les petits fichiers sont exécutées en raison d'une génération excessive de petits fichiers.

  2. À l'étape de terminaison, la tâche SQL prend beaucoup de temps dans le cluster de contrôle. Par exemple, la tâche met à jour les métadonnées des partitions dynamiques. La section suivante fournit des exemples de scénarios courants.

  • Exécution de sous-requêtes à plusieurs étapes

    Dans la plupart des cas, les sous-requêtes de MaxCompute SQL sont compilées dans le même DAG Fuxi. Par conséquent, toutes les sous-requêtes et les requêtes principales sont terminées par une seule tâche Fuxi. Cependant, certaines sous-requêtes spéciales doivent être exécutées séparément avant les requêtes principales. Exemple de code :

    SELECT
         product,
        sum(price)
     FROM
         sales
     WHERE
         ds in (SELECT DISTINCT ds FROM t_ds_set)
     GROUP BY product;

    La sous-requête SELECT DISTINCT ds FROM t_ds_set est exécutée en premier, et son résultat est nécessaire pour l'élimination des partitions afin d'optimiser le nombre de partitions lues par la requête principale. Ces deux exécutions constituent des tâches Fuxi distinctes. Dans LogView, chaque tâche Fuxi apparaît dans un onglet séparé, tel que SQL_0_0_0_job_0 et SQL_0_0_1_job_1. Le DAG affiche également les dépendances entre plusieurs nœuds JOB. Cliquez simplement sur le deuxième tab pour afficher l'état d'exécution de job_1. Après le changement, vous pouvez voir l'état actuel (tel que Running ou Waiting) de chaque tâche dans job_1.

  • Petits fichiers excessifs

    Les petits fichiers excessifs affectent principalement les performances de stockage et de calcul.

    • Stockage : Les petits fichiers excessifs augmentent la charge de travail sur le système de fichiers distribué Apsara. Cela affecte l'utilisation du stockage.

    • Calcul : Les performances globales de traitement sont affectées, car l'efficacité de traitement de MaxCompute sur un seul fichier volumineux est supérieure à celle sur plusieurs petits fichiers. Par conséquent, lorsqu'une tâche SQL est terminée, l'opération de fusion des petits fichiers est automatiquement déclenchée si certaines conditions sont remplies. Cela permet d'éviter que le système ne génère trop de petits fichiers.

  • Si des petits fichiers excessifs existent, les instructions SELECT peuvent s'exécuter pendant une longue période lorsqu'une tâche est à l'étape de terminaison. Lorsque le système génère et affiche les résultats d'exécution des instructions SELECT, il doit ouvrir un grand nombre de petits fichiers pour lire les données. Ce processus prend du temps. Pour éviter que le système ne génère un grand nombre de résultats d'exécution, nous vous recommandons de ne pas utiliser d'instructions SELECT. Vous pouvez utiliser les commandes Tunnel pour télécharger les données. Si le nombre de résultats d'exécution n'est pas important mais que le nombre de fichiers est excessif, nous vous recommandons de vérifier si le paramètre odps.merge.smallfile.filesize.threshold est correctement configuré. Pour plus d'informations sur la fusion des petits fichiers, reportez-vous à Fusionner les petits fichiers.

    Solution : Vous pouvez vérifier dans LogView si la tâche a déclenché une fusion automatique des petits fichiers. Comme pour l'exécution de sous-requêtes à plusieurs étapes, la tâche de fusion apparaît dans un onglet séparé. Le nom de l'onglet d'une tâche de fusion peut ressembler à SQL_0_0_0_merge et affiche la progression de la MergeTask. Bien que cela ajoute du temps à l'exécution totale de la tâche, cela aboutit à un nombre et une taille de fichiers plus raisonnables dans la table de sortie. Cela évite une pression excessive sur le système de fichiers et améliore les performances de lecture pour les tâches ultérieures qui utilisent la table.

  • Mise à jour des métadonnées dans les partitions dynamiques

    Description du problème : Une fois une tâche Fuxi terminée, vous devrez peut-être effectuer certaines opérations liées aux métadonnées. Par exemple, si vous souhaitez déplacer les données de résultat vers un répertoire spécifique et mettre à jour les métadonnées de la table, un grand nombre de partitions peut être généré dans la table lors du partitionnement dynamique. Par conséquent, le processus prend du temps. Par exemple, l'instruction insert into ... values est exécutée pour la table partitionnée sales afin d'ajouter 2 000 partitions. Exemple d'instruction :

    INSERT INTO TABLE sales partition (ds)(ds, product, price)
    VALUES ('20170101','a',1),('20170102','b',2),('20170103','c',3), ...;

    Après la fin de la tâche Fuxi, la mise à jour des métadonnées de la table prend encore du temps. L'historique SubStatusHistory de LogView indique que la tâche est bloquée à SQLTask is updating meta information. Cela correspond au code d'état 1260, et vous pouvez vérifier sa valeur Latency pour voir combien de temps la mise à jour des métadonnées a pris.

  • Augmentation de la taille du fichier de sortie

    Symptôme : Les données peuvent s'étendre de plusieurs fois même si les nombres d'enregistrements d'entrée et de sortie sont similaires. Dans la colonne IO Bytes de Fuxi Jobs, vous pouvez comparer les tailles de données d'entrée et de sortie de chaque Task pour identifier l'étape à laquelle l'expansion des données s'est produite.

    Solution : Une cause est un changement de distribution des données, qui affecte la compression. Lors du processus d'écriture des données dans une table, les données sont compressées. Les algorithmes de compression atteignent le taux de compression le plus élevé sur les données répétitives. Par conséquent, si des données identiques sont regroupées lors du processus d'écriture, un taux de compression élevé peut être atteint. La distribution des données dépend largement de la manière dont les données sont brassées (shuffled) et triées lors de l'étape d'écriture (R12 dans Fuxi Jobs). Dans cet exemple, la dernière opération SQL est une JOIN, avec la clé de jointure suivante :

    on  t1.query = t2.query and t1.item_id=t2.item_id

    Les caractéristiques des données indiquent que la plupart des colonnes sont des attributs d'articles. Dans ce cas, toutes les colonnes pour les articles ayant le même item_id sont identiques. Par conséquent, tous les articles de la requête sont triés dans un ordre aléatoire. Cela entraîne un faible taux de compression. L'exemple de code suivant montre comment modifier la séquence de jointure. Après la modification, la taille des données est réduite à 1/3 de la taille d'origine.

    on t1.item_id=t2.item_id and t1.query = t2.query

    Après la modification, la taille des données est réduite à 1/3 de la taille d'origine.

    Dans un autre cas, les opérations de brassage (shuffle) générées par JOIN ou GROUP BY ne contiennent pas la colonne de tri la plus adaptée à la compression. Dans ce cas, vous pouvez utiliser la clause ZORDER BY pour trier les éléments sur votre machine locale. Ainsi, vous pouvez obtenir un taux de compression élevé à moindre coût. Vous pouvez également exécuter une instruction DISTRIBUTED BY SORT BY pour réorganiser manuellement la distribution des données. Cette méthode nécessite une longue période de calcul des données et une utilisation élevée du CPU.