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 TABLEpara 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 PARTITIONScomo el siguiente para enumerar las particiones.<table_name>SHOW PARTITIONS lineitem_parq_partitionedLos 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_partitionedy se utiliza la cláusulaWHEREpara restringir laDATEa 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 PARTITIONSpara 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 INTOpara 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 INTOque 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.