Uso de CTAS e INSERT INTO para evitar el límite de 100 particiones
Athena tiene un límite de 100 particiones por consulta CREATE TABLE AS SELECT
(CTAS). Del mismo modo, puede añadir un máximo de 100 particiones a una tabla de destino con una instrucción INSERT INTO.
Si supera esta limitación, es posible que reciba el mensaje de error HIVE_TOO_MANY_OPEN_PARTITIONS: Exceeded limit of 100 open writers for partitions/buckets
(HIVE_TOO_MANY_OPEN_PARTITIONS: Se ha superado el límite de 100 autores abiertos para particiones/buckets). Para evitar esta limitación, puede utilizar una instrucción CTAS y una serie de instrucciones INSERT INTO
que crean o insertan hasta 100 particiones cada una.
En el ejemplo de este tema se utiliza una base de datos llamada tpch100
cuyos datos residen en la ubicación del bucket de Amazon S3 s3://amzn-s3-demo-bucket/.
Para utilizar CTAS e INSERT INTO para crear una tabla de más de 100 particiones
-
Utilice una instrucción
CREATE EXTERNAL TABLE
para crear una tabla con particiones en el campo que desee.La siguiente instrucción de ejemplo divide los datos mediante la columna
l_shipdate
. La tabla tiene 2525 particiones.CREATE EXTERNAL TABLE `tpch100.lineitem_parq_partitioned`( `l_orderkey` int, `l_partkey` int, `l_suppkey` int, `l_linenumber` int, `l_quantity` double, `l_extendedprice` double, `l_discount` double, `l_tax` double, `l_returnflag` string, `l_linestatus` string, `l_commitdate` string, `l_receiptdate` string, `l_shipinstruct` string, `l_comment` string) PARTITIONED BY ( `l_shipdate` string) ROW FORMAT SERDE 'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe' STORED AS INPUTFORMAT 'org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat' OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat' LOCATION 's3://amzn-s3-demo-bucket/lineitem/'
-
Ejecute un comando
SHOW PARTITIONS
como el siguiente para enumerar las particiones.<table_name>
SHOW PARTITIONS lineitem_parq_partitioned
Los siguientes son resultados parciales de la muestra.
/* l_shipdate=1992-01-02 l_shipdate=1992-01-03 l_shipdate=1992-01-04 l_shipdate=1992-01-05 l_shipdate=1992-01-06 ... l_shipdate=1998-11-24 l_shipdate=1998-11-25 l_shipdate=1998-11-26 l_shipdate=1998-11-27 l_shipdate=1998-11-28 l_shipdate=1998-11-29 l_shipdate=1998-11-30 l_shipdate=1998-12-01 */
-
Ejecute una consulta CTAS para crear una tabla con particiones.
En el siguiente ejemplo se crea una tabla llamada
my_lineitem_parq_partitioned
y se utiliza la cláusulaWHERE
para restringir laDATE
a antes de1992-02-01
. Dado que el conjunto de datos de muestra comienza en enero de 1992, solo se crean particiones para enero de 1992.CREATE table my_lineitem_parq_partitioned WITH (partitioned_by = ARRAY['l_shipdate']) AS SELECT l_orderkey, l_partkey, l_suppkey, l_linenumber, l_quantity, l_extendedprice, l_discount, l_tax, l_returnflag, l_linestatus, l_commitdate, l_receiptdate, l_shipinstruct, l_comment, l_shipdate FROM tpch100.lineitem_parq_partitioned WHERE cast(l_shipdate as timestamp) < DATE ('1992-02-01');
-
Ejecute el comando
SHOW PARTITIONS
para comprobar que la tabla contiene las particiones que desea.SHOW PARTITIONS my_lineitem_parq_partitioned;
Las particiones del ejemplo son de enero de 1992.
/* l_shipdate=1992-01-02 l_shipdate=1992-01-03 l_shipdate=1992-01-04 l_shipdate=1992-01-05 l_shipdate=1992-01-06 l_shipdate=1992-01-07 l_shipdate=1992-01-08 l_shipdate=1992-01-09 l_shipdate=1992-01-10 l_shipdate=1992-01-11 l_shipdate=1992-01-12 l_shipdate=1992-01-13 l_shipdate=1992-01-14 l_shipdate=1992-01-15 l_shipdate=1992-01-16 l_shipdate=1992-01-17 l_shipdate=1992-01-18 l_shipdate=1992-01-19 l_shipdate=1992-01-20 l_shipdate=1992-01-21 l_shipdate=1992-01-22 l_shipdate=1992-01-23 l_shipdate=1992-01-24 l_shipdate=1992-01-25 l_shipdate=1992-01-26 l_shipdate=1992-01-27 l_shipdate=1992-01-28 l_shipdate=1992-01-29 l_shipdate=1992-01-30 l_shipdate=1992-01-31 */
-
Utilice una instrucción
INSERT INTO
para añadir particiones a la tabla.En el siguiente ejemplo se añaden particiones para las fechas del mes de febrero de 1992.
INSERT INTO my_lineitem_parq_partitioned SELECT l_orderkey, l_partkey, l_suppkey, l_linenumber, l_quantity, l_extendedprice, l_discount, l_tax, l_returnflag, l_linestatus, l_commitdate, l_receiptdate, l_shipinstruct, l_comment, l_shipdate FROM tpch100.lineitem_parq_partitioned WHERE cast(l_shipdate as timestamp) >= DATE ('1992-02-01') AND cast(l_shipdate as timestamp) < DATE ('1992-03-01');
-
Vuelva a ejecutar
SHOW PARTITIONS
.SHOW PARTITIONS my_lineitem_parq_partitioned;
La tabla de muestra tiene ahora particiones tanto de enero como de febrero de 1992.
/* l_shipdate=1992-01-02 l_shipdate=1992-01-03 l_shipdate=1992-01-04 l_shipdate=1992-01-05 l_shipdate=1992-01-06 ... l_shipdate=1992-02-20 l_shipdate=1992-02-21 l_shipdate=1992-02-22 l_shipdate=1992-02-23 l_shipdate=1992-02-24 l_shipdate=1992-02-25 l_shipdate=1992-02-26 l_shipdate=1992-02-27 l_shipdate=1992-02-28 l_shipdate=1992-02-29 */
-
Siga utilizando instrucciones
INSERT INTO
que lean y no agreguen más de 100 particiones cada una. Continúe hasta que alcance el número de particiones necesario.importante
Al establecer la condición
WHERE
, asegúrese de que las consultas no se superpongan. De lo contrario, algunas particiones podrían tener datos duplicados.