Partitionnement et compartimentation dans Athena - Amazon Athena

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Partitionnement et compartimentation dans Athena

Le partitionnement et la compartimentation sont deux moyens de réduire la quantité de données qu'Athena doit analyser lorsque vous exécutez une requête. Le partitionnement et la compartimentation sont complémentaires et peuvent être utilisés ensemble. La réduction de la quantité de données analysées permet d'améliorer les performances et de réduire les coûts. Pour des instructions générales sur les performances des requêtes Athena, consultez 10 meilleurs conseils de réglage des performances pour Amazon Athena.

Qu'est-ce que le partitionnement ?

Le partitionnement consiste à organiser les données dans des répertoires (ou « préfixes ») sur Amazon S3 en fonction d'une propriété particulière des données. Ces propriétés sont appelées clés de partition. Une clé de partition courante est la date ou une autre unité de temps telle que l'année ou le mois. Cependant, un jeu de données peut être partitionné par plusieurs clés. Par exemple, les données relatives aux ventes de produits peuvent être partitionnées par date, catégorie de produit et marché.

Choix du mode de partitionnement

Les propriétés qui sont toujours ou fréquemment utilisées dans les requêtes et qui ont une faible cardinalité peuvent être utilisées comme clés de partition. Il y a un compromis entre le fait d'avoir trop de partitions et d'en avoir trop peu. Lorsque le nombre de partitions est trop élevé, l'augmentation du nombre de fichiers entraîne une surcharge. Le filtrage des partitions elles-mêmes entraîne également une certaine surcharge. Lorsque le nombre de partitions est trop faible, les requêtes doivent souvent analyser davantage de données.

Création d'une table partitionnée

Lorsqu'un jeu de données est partitionné, vous pouvez créer une table partitionnée dans Athena. Une table partitionnée est une table qui possède des clés de partition. Lorsque vous utilisez CREATE TABLE, vous ajoutez des partitions à la table. Lorsque vous utilisez CREATE TABLE AS, les partitions créées sur Amazon S3 sont automatiquement ajoutées à la table.

Dans une instruction CREATE TABLE, vous spécifiez les clés de partition dans la clause PARTITIONED BY (column_name data_type). Dans une instruction CREATE TABLE AS, vous spécifiez les clés de partition dans une clause WITH (partitioned_by = ARRAY['partition_key']) ou WITH (partitioning = ARRAY['partition_key']) pour les tables Iceberg. Pour des raisons de performances, les clés de partition doivent toujours être de type STRING. Pour plus d’informations, consultez Utiliser STRING comme type de données pour les clés de partition.

Pour des informations de syntaxe CREATE TABLE et CREATE TABLE AS supplémentaires, consultez CREATE TABLE et Propriétés de la table CTAS.

Interrogation de tables partitionnées

Lorsque vous interrogez une table partitionnée, Athena utilise les prédicats de la requête pour filtrer la liste des partitions. Il utilise ensuite les emplacements des partitions correspondantes pour traiter les fichiers trouvés. Athena peut réduire efficacement la quantité de données analysées en ne lisant simplement pas les données contenues dans les partitions qui ne correspondent pas aux prédicats de la requête.

Exemples

Supposons que vous ayez une table partitionnée par sales_date et product_category et que vous souhaitiez connaître le chiffre d'affaires total sur une semaine dans une catégorie spécifique. Vous incluez des prédicats dans les colonnes sales_date et product_category pour vous assurer qu'Athena analyse uniquement la quantité minimale de données, comme dans l'exemple suivant.

SELECT SUM(amount) AS total_revenue FROM sales WHERE sales_date BETWEEN '2023-02-27' AND '2023-03-05' AND product_category = 'Toys'

Supposons que vous disposiez d'un jeu de données partitionné par date mais également doté d'un horodatage précis.

Avec les tables Iceberg, vous pouvez déclarer qu'une clé de partition a une relation avec une colonne, mais avec les tables Hive, le moteur de requête n'a aucune connaissance des relations entre les colonnes et les clés de partition. Pour cette raison, vous devez inclure un prédicat à la fois sur la colonne et sur la clé de partition de votre requête afin de vous assurer que celle-ci n'analyse pas plus de données que nécessaire.

Supposons, par exemple, que la table sales de l'exemple précédent comporte également une colonne sold_at du type de données TIMESTAMP. Si vous souhaitez obtenir le chiffre d'affaires uniquement pour une période spécifique, vous devez écrire la requête comme suit :

SELECT SUM(amount) AS total_revenue FROM sales WHERE sales_date = '2023-02-28' AND sold_at BETWEEN TIMESTAMP '2023-02-28 10:00:00' AND TIMESTAMP '2023-02-28 12:00:00' AND product_category = 'Toys'

Pour plus d'informations sur cette différence entre l'interrogation des tables Hive et Iceberg, consultez Comment écrire des requêtes pour des champs d'horodatage qui sont également partitionnés dans le temps.

Qu'est-ce que la compartimentation ?

La compartimentation est une méthode pour organiser les enregistrements d'un jeu de données en catégories appelées compartiments.

La présente signification des termes compartiment et compartimentation diffère de celle des compartiments Amazon S3 et ne doit pas être confondue avec celle-ci. Lors de la compartimentation des données, les enregistrements ayant la même valeur pour une propriété sont placés dans le même compartiment. Les enregistrements sont répartis aussi uniformément que possible entre les compartiments afin que chaque compartiment contienne à peu près la même quantité de données.

Dans la pratique, les compartiments sont des fichiers, et une fonction de hachage détermine le compartiment dans lequel un enregistrement est placé. Un jeu de données compartimenté comportera un ou plusieurs fichiers par compartiment et par partition. Le compartiment auquel appartient un fichier est codé dans le nom du fichier.

Avantages de la compartimentation

La compartimentation est utile lorsqu'un jeu de données est compartimenté par une certaine propriété et que vous souhaitez récupérer des enregistrements dans lesquels cette propriété possède une certaine valeur. Comme les données sont compartimentées, Athena peut utiliser la valeur pour déterminer les fichiers à consulter. Supposons, par exemple, qu'un jeu de données soit compartimenté par customer_id et que vous souhaitiez rechercher tous les enregistrements d'un client spécifique. Athena détermine le compartiment qui contient ces enregistrements et ne lit que les fichiers qu'il contient.

Les colonnes présentant une cardinalité élevée (c'est-à-dire comportant de nombreuses valeurs distinctes), qui sont distribuées de manière uniforme et que vous interrogez fréquemment concernant des valeurs spécifiques se prêtent bien à la compartimentation.

Note

Athena ne prend pas en charge l'utilisation INSERT INTO pour ajouter de nouveaux enregistrements à des tables compartimentées.

Types de données pris en charge pour le filtrage sur les colonnes compartimentées

Vous pouvez ajouter des filtres sur des colonnes compartimentées contenant certains types de données. Athena prend en charge le filtrage uniquement sur les colonnes compartimentées avec les types de données suivants :

  • BOOLEAN

  • BYTE

  • DATE

  • DOUBLE

  • FLOAT

  • INT

  • LONG

  • SHORT

  • CHAÎNE

  • VARCHAR

Prise en charge de Hive et Spark

La version 2 du moteur Athena prend en charge les jeux de données compartimentés à l'aide de l'algorithme de compartiment Hive, et la version 3 du moteur Athena prend également en charge l'algorithme de compartimentation Apache Spark. La compartimentation Hive est le méthode par défaut. Si votre jeu de données est compartimenté à l'aide de l'algorithme Spark, utilisez la clause TBLPROPERTIES pour définir la valeur de la propriété bucketing_format sur spark.

Note

Athena a une limite de 100 partitions dans une requête CREATE TABLE AS SELECT (CTAS). De même, vous pouvez ajouter un maximum de 100 partitions à une table de destination avec une instruction INSERT INTO. Cette limite de 100 ne s'applique que lorsque la table est compartimentée et partitionnée.

Si vous dépassez cette limite, le message d'erreur HIVE_TOO_MANY_OPEN_PARTITIONS: Exceeded limit of 100 open writers for partitions/buckets (Dépassement de la limite de 100 rédacteurs ouverts pour les partitions/compartiments) peut s'afficher. Pour contourner ces limitations, vous pouvez utiliser une instruction CTAS et une série d'instructions INSERT INTO qui créent ou insèrent jusqu'à 100 partitions chacune. Pour plus d’informations, consultez Utilisation de CTAS et de INSERT INTO pour contourner la limite de 100 partitions.

Exemple de compartimentation CREATE TABLE

Pour créer une table pour un jeu de données compartimenté existant, utilisez la clause CLUSTERED BY (column) suivie de la clause INTO N BUCKETS. La clause INTO N BUCKETS spécifie le nombre de compartiments dans lesquels les données sont compartimentées.

Dans l'exemple CREATE TABLE suivant, le jeu de données sales est compartimenté par customer_id en 8 compartiments à l'aide de l'algorithme Spark. L'instruction CREATE TABLE utilise les clauses CLUSTERED BY et TBLPROPERTIES pour définir les propriétés en conséquence.

CREATE EXTERNAL TABLE sales (...) ... CLUSTERED BY (`customer_id`) INTO 8 BUCKETS ... TBLPROPERTIES ( 'bucketing_format' = 'spark' )

Exemple de compartimentation CREATE TABLE AS (CTAS)

Pour spécifier la compartimentation avec CREATE TABLE AS, utilisez les paramètres bucketed_by et bucket_count, comme dans l'exemple suivant.

CREATE TABLE sales WITH ( ... bucketed_by = ARRAY['customer_id'], bucket_count = 8 ) AS SELECT ...

Exemple de requête de compartimentation

L'exemple de requête suivant recherche les noms de produits qu'un client spécifique a achetés au cours d'une semaine.

SELECT DISTINCT product_name FROM sales WHERE sales_date BETWEEN '2023-02-27' AND '2023-03-05' AND customer_id = 'c123'

Si cette table est partitionnée par sales_date et compartimentée par customer_id, Athena peut calculer le compartiment dans lequel se trouvent les enregistrements du client. Athena lit tout au plus un fichier par partition.

Ressources supplémentaires