Este tópico explica como avaliar a eficácia do partition pruning.
Contexto
No MaxCompute, é possível definir um ou mais campos como colunas de partição ao criar uma tabela particionada. Durante a consulta dos dados, especifique um nome de partição para ler apenas os dados da partição correspondente. Essa abordagem evita uma varredura completa na tabela, o que melhora a eficiência do processamento e reduz custos.
O partition pruning consiste em aplicar condições de filtro às colunas de partição. Isso permite que uma consulta SQL leia apenas um subconjunto de partições em vez de realizar uma varredura completa na tabela, economizando recursos e aumentando a eficiência da consulta. No entanto, é comum que o partition pruning falhe.
Este tópico aborda dois aspectos do partition pruning:
Como determinar se o partition pruning está funcionando corretamente.
Análise de cenários em que o partition pruning falha.
Determinar se o partition pruning é eficaz
Utilize o comando EXPLAIN para visualizar o plano de execução da SQL e verificar se o partition pruning está surtindo efeito.
-
Partition pruning ineficaz.
explain select seller_id from xxxxx_trd_slr_ord_1d where ds=rand();O plano de execução indica que a consulta SQL lê todas as 1.344 partições da tabela.
-
Partition pruning eficaz.
explain select seller_id from xxxxx_trd_slr_ord_1d where ds='20150801';In Task M1 Stg1: Data source:rd_slr_ord_id/dtrd_slr_ord_id/ds=20150801 TS: alias: rd_slr_ord_id/dtrd_slr_ord_id FIL: EQUAL(rd_slr_ord_id/dtrd_slr_ord_id.ds, '20150801') SEL: rd_slr_ord_id/dtrd_slr_ord_id.seller_idO plano de execução mostra que a consulta SQL lê apenas a partição 20150801 da tabela.
Cenários de falha no partition pruning
-
Falha causada por função definida pelo usuário
O partition pruning pode falhar se a condição de filtro em uma coluna de partição utilizar uma função definida pelo usuário (UDF) ou certas funções internas. Portanto, caso utilize uma função não padrão para filtrar valores de partição, execute o comando EXPLAIN para visualizar o plano de execução e confirme se o partition pruning está ativo.
explain select ... from xxxxx_base2_brd_ind_cw where ds = concat(SPLIT_PART(bi_week_dim(' ${bdp.system.bizdate}'), ',', 1), SPLIT_PART(bi_week_dim(' ${bdp.system.bizdate}'), ',', 2))NotaAs UDFs agora oferecem suporte ao partition pruning. Para obter mais informações, consulte a descrição em WHERE clause (WHERE_condition).
-
Falha ao usar JOINs
Ao utilizar JOIN em uma instrução SQL:
Se as condições de filtro de partição estiverem na cláusula WHERE, o partition pruning entrará em vigor.
Caso as condições de filtro de partição estejam na cláusula ON, o pruning será eficaz para a tabela à direita em um LEFT JOIN, mas não para a tabela à esquerda.
Esta seção descreve o comportamento para três tipos de JOINs:
-
LEFT OUTER JOIN
-
Todas as condições de filtro de partição estão na cláusula ON
set odps.sql.allow.fullscan=true; explain select a.seller_id ,a.pay_ord_pbt_1d_001 from xxxxx_trd_slr_ord_1d a left outer join xxxxx_seller b on a.seller_id=b.user_id and a.ds='20150801' and b.ds='20150801';Após executar a instrução
explainanterior, o plano de execução é retornado conforme abaixo. O plano mostra que a fonte de dados da tabela à esquerda varre todas as 1.770 partições e a condição de filtro é enviada para o operador FIL:In Task M2_Stg1: Data source: xxx ller/ds=20101001, xxx seller/ds=20101002, xxx seller/ds=20101003...(total 1770) xxx RS: order: + optimizeOrderBy: False valueDestLimit: 0 keys: b.user_id values: b.ds partitions b.user_id In Task J3_1_2_Stg1: JOIN: a LEFT OUTER JOIN b filter: 0: 1: FIL: And(EQUAL(a. col96, '20150801'), EQUAL(b. col209, '20150801')) SEL: xxx FS: output: NoneA saída anterior demonstra que uma varredura completa da tabela é realizada na tabela à esquerda, enquanto o partition pruning é eficaz para a tabela à direita.
-
Todas as condições de filtro de partição estão na cláusula WHERE
set odps.sql.allow.fullscan=true; explain select a.seller_id ,a.pay_ord_pbt_1d_001 from xxxxx_trd_slr_ord_1d a left outer join xxxxx_seller b on a.seller_id=b.user_id where a.ds='20150801' and b.ds='20150801';Task M2_Stg1: Data source: xxx/ds=seller/ds=20150801 TS: alias: b FIL: EQUAL(b.ds, '20150801') RS: order: + optimizeOrderBy: False valueDestLimit: 0 keys: b.user_id values: partitions: b.user_id In Task J3_1_2_Stg1: JOIN: a LEFT OUTER JOIN unknown filter: 0: 1: SEL: a._col0, a._col20 FS: output: None In Task M1_Stg1: Data source: xxx/ds= trd slr ord 1d/ds=20150801 TS: alias: aO plano de execução confirma que o partition pruning funciona para ambas as tabelas.
-
-
RIGHT OUTER JOIN
De forma semelhante ao LEFT OUTER JOIN, se as condições de filtro de partição estiverem na cláusula ON de um RIGHT OUTER JOIN, o partition pruning será eficaz apenas para a tabela à esquerda. Quando as condições estiverem na cláusula WHERE, o pruning funcionará para ambas as tabelas.
-
FULL OUTER JOIN
Em um FULL OUTER JOIN, as condições de filtro de partição são eficazes somente se estiverem na cláusula WHERE. Se estiverem na cláusula ON, o partition pruning não funcionará para nenhuma das tabelas.
Precauções
Falhas no partition pruning podem causar impactos significativos e costumam ser difíceis de detectar. Por isso, verifique a ocorrência dessas falhas antes de confirmar seu código.
Para utilizar o partition pruning com uma função definida pelo usuário, modifique a classe ou adicione
set odps.sql.udf.ppr.deterministic = true;antes da instrução SQL. Para mais detalhes, consulte WHERE clause (WHERE_condition).