O MaxCompute permite reescrever consultas SQL originais para usar uma materialized view quando as consultas contêm condições de filtro ou determinados tipos de operadores.
Observações de uso
O princípio fundamental da reescrita de consultas em materialized views é que a materialized view deve conter todos os dados necessários à consulta. Isso inclui colunas de saída e quaisquer colunas usadas em condições de filtro, funções de agregação ou condições de JOIN. A reescrita não ocorre se a consulta exigir colunas ausentes na materialized view ou se usar uma função de agregação não suportada.
-
Para ativar a reescrita de consultas em materialized views, adicione a seguinte configuração antes da instrução de consulta:
SET odps.sql.materialized.view.enable.auto.rewriting=true;A reescrita de consultas não é suportada quando uma materialized view está em estado inválido. Nesse caso, a consulta executa diretamente na tabela source, sem aceleração.
-
Reescrita entre projetos
Por padrão, um projeto do MaxCompute só pode usar suas próprias materialized views para reescrita de consultas. Para usar materialized views de outros projetos, especifique uma lista de projetos do MaxCompute permitidos adicionando a seguinte configuração antes da consulta:
SET odps.sql.materialized.view.source.project.white.list = <project_name1>,<project_name2>,<project_name3>; -
Para ativar reescritas que usam materialized views definidas com
LEFT/RIGHT JOINouUNION ALL, adicione a seguinte configuração antes da instrução de consulta:SET odps.sql.materialized.view.enable.substitute.rewriting=true;
Tipos de operadores suportados
A tabela a seguir compara os tipos de operadores de reescrita de consultas suportados pelo MaxCompute com os de outros products.
Tipo de operador | Classificação | MaxCompute | BigQuery | Amazon Redshift | Hive |
FILTER | Correspondência total de expressão | Suportado | Suportado | Suportado | Suportado |
Correspondência parcial de expressão | Suportado | Suportado | Suportado | Suportado | |
AGGREGATE | AGGREGATE único | Suportado | Suportado | Suportado | Suportado |
Múltiplos AGGREGATEs | Não suportado | Não suportado | Não suportado | Não suportado | |
JOIN | Tipo de JOIN | INNER JOIN | Não suportado | INNER JOIN | INNER JOIN |
JOIN único | Suportado | Não suportado | Suportado | Suportado | |
Múltiplos JOINs | Suportado | Não suportado | Suportado | Suportado | |
AGGREGATE+JOIN | - | Suportado | Não suportado | Suportado | Suportado |
Exemplos
Exemplo 1: Reescrita com condições de filtro
-
Crie uma materialized view.
CREATE MATERIALIZED VIEW mv AS SELECT a,b,c FROM src WHERE a>5; -
A tabela a seguir apresenta exemplos de reescrita para a materialized view.
Consulta original
Consulta reescrita
SELECT a,b FROM src WHERE a>5;SELECT a,b FROM mv;SELECT a, b FROM src WHERE a=10;SELECT a,b FROM mv WHERE a=10;SELECT a, b FROM src WHERE a=10 AND b='3';SELECT a,b FROM mv WHERE a=10 AND b=3;SELECT a, b FROM src WHERE a>3;(SELECT a,b FROM src WHERE a>3 AND a<=5) UNION (SELECT a,b FROM mv);SELECT a, b FROM src WHERE a=10 AND d=4;A reescrita falha porque a materialized view não contém a coluna
d.SELECT d, e FROM src WHERE a=10;A reescrita falha porque a materialized view não contém as colunas
dee.SELECT a, b FROM src WHERE a=1;A reescrita falha porque a materialized view não contém dados onde
a=1.
Exemplo 2: Reescrita com funções de agregação
Todas as funções de agregação podem ser reescritas se a materialized view e a consulta compartilharem a mesma chave de agregação. Se as chaves de agregação forem diferentes, apenas reescritas usando SUM, MIN e MAX são suportadas.
-
Crie uma materialized view.
CREATE MATERIALIZED VIEW mv AS SELECT a, b, sum(c) AS sum, count(d) AS cnt FROM src GROUP BY a, b; -
A tabela a seguir mostra como as consultas são reescritas com base na materialized view.
Consulta original
Consulta reescrita
SELECT a, sum(c) FROM src GROUP BY a;SELECT a, sum(sum) FROM mv GROUP BY a;SELECT a, count(d) FROM src GROUP BY a, b;SELECT a, cnt FROM mv;SELECT a, count(b) FROM (SELECT a, b FROM src GROUP BY a, b) GROUP BY a;SELECT a,count(b) FROM mv GROUP BY a;SELECT a,count(b) FROM mv GROUP BY a;A reescrita falha porque a view já agregou as colunas
aeb, portanto a colunabnão pode ser agregada novamente.SELECT a, count(c) FROM src GROUP BY a;A reescrita falha porque a reagregação da função
COUNTnão é suportada.
Se uma função de agregação contiver DISTINCT, a consulta só poderá ser reescrita se a materialized view e a consulta original tiverem a mesma chave de agregação. Caso contrário, a reescrita não será possível.
-
Crie uma materialized view.
CREATE MATERIALIZED VIEW mv AS SELECT a, b, sum(DISTINCT c) AS sum, count(DISTINCT d) AS cnt FROM src GROUP BY a, b; -
A tabela a seguir ilustra como as consultas são reescritas com base na materialized view.
Consulta original
Consulta reescrita
SELECT a, count(DISTINCT d) FROM src GROUP BY a, b;SELECT a, cnt FROM mv;SELECT a, count(c) FROM src GROUP BY a, b;A reescrita falha porque a reagregação da função
COUNTnão é suportada.SELECT a, count(DISTINCT c) FROM src GROUP BY a;A reescrita falha porque a coluna
arequer outra agregação.
Exemplo 3: Reescrita com cláusula JOIN
Reescrever entradas de JOIN
-
Crie materialized views.
CREATE MATERIALIZED VIEW mv1 AS SELECT a, b FROM j1 WHERE b > 10; CREATE MATERIALIZED VIEW mv2 AS SELECT a, b FROM j2 WHERE b > 10; -
A tabela a seguir demonstra como as consultas são reescritas com base nas materialized views.
Consulta original
Consulta reescrita
SELECT j1.a,j1.b,j2.a FROM (SELECT a,b FROM j1 WHERE b > 10) j1 JOIN j2 ON j1.a=j2.a;SELECT mv1.a, mv1.b, j2.a FROM mv1 JOIN j2 ON mv1.a=j2.a;SELECT j1.a,j1.b,j2.a FROM (SELECT a,b FROM j1 WHERE b > 10) j1 JOIN (SELECT a,b FROM j2 WHERE b > 10) j2 ON j1.a=j2.a;SELECT mv1.a,mv1.b,mv2.a FROM mv1 JOIN mv2 ON mv1.a=mv2.a;
JOIN com condições de filtro
-
Crie materialized views.
--Create a non-partitioned materialized view. CREATE MATERIALIZED VIEW mv1 AS SELECT j1.a, j1.b FROM j1 JOIN j2 ON j1.a=j2.a; CREATE MATERIALIZED VIEW mv2 AS SELECT j1.a, j1.b FROM j1 JOIN j2 ON j1.a=j2.a WHERE j1.a > 10; --Create a partitioned materialized view. CREATE MATERIALIZED VIEW mv LIFECYCLE 7 PARTITIONED BY (ds) AS SELECT t1.id, t1.ds AS ds FROM t1 JOIN t2 ON t1.id = t2.id; -
A tabela a seguir mostra como as consultas são reescritas com base nas materialized views.
Consulta original
Consulta reescrita
SELECT j1.a,j1.b FROM j1 JOIN j2 ON j1.a=j2.a WHERE j1.a=4;SELECT a, b FROM mv1 WHERE a=4;SELECT j1.a,j1.b FROM j1 JOIN j2 ON j1.a=j2.a WHERE j1.a > 20;SELECT a,b FROM mv2 WHERE a>20;SELECT j1.a,j1.b FROM j1 JOIN j2 ON j1.a=j2.a WHERE j1.a > 5;(SELECT j1.a,j1.b FROM j1 JOIN j2 ON j1.a=j2.a WHERE j1.a > 5 AND j1.a <= 10) UNION SELECT * FROM mv2;SELECT key FROM t1 JOIN t2 ON t1.id= t2.id WHERE t1.ds='20210306';SELECT key FROM mv WHERE ds='20210306';SELECT key FROM t1 JOIN t2 ON t1.id= t2.id WHERE t1.ds>='20210306';SELECT key FROM mv WHERE ds>='20210306';SELECT j1.a,j1.b FROM j1 JOIN j2 ON j1.a=j2.a WHERE j2.a=4;A reescrita falha porque a materialized view não contém a coluna
j2.a.
Estender um JOIN
-
Crie uma materialized view.
CREATE MATERIALIZED VIEW mv AS SELECT j1.a, j1.b FROM j1 JOIN j2 ON j1.a=j2.a; -
A tabela a seguir mostra como as consultas são reescritas com base na materialized view.
Consulta original
Consulta reescrita
SELECT j1.a, j1.b FROM j1 JOIN j2 JOIN j3 ON j1.a=j2.a AND j1.a=j3.a;SELECT mv.a, mv.b FROM mv JOIN j3 ON mv.a=j3.a;SELECT j1.a, j1.b FROM j1 JOIN j2 JOIN j3 ON j1.a=j2.a AND j2.a=j3.a;SELECT mv.a,mv.b FROM mv JOIN j3 ON mv.a=j3.a;
É possível combinar esses três cenários de reescrita de JOIN.
Como o objetivo da reescrita de consultas em materialized views é acelerar as consultas, o MaxCompute prioriza regras de reescrita que oferecem o melhor desempenho. Uma regra não é aplicada se introduzir operações que resultem em baixa aceleração.
Exemplo 4: Reescrita com cláusula LEFT JOIN
-
Crie uma materialized view.
CREATE MATERIALIZED VIEW mv LIFECYCLE 7( user_id, job, total_amount ) AS SELECT t1.user_id, t1.job, sum(t2.order_amount) AS total_amount FROM user_info AS t1 LEFT JOIN sale_order AS t2 ON t1.user_id=t2.user_id GROUP BY t1.user_id; -
A tabela a seguir mostra como uma consulta é reescrita com base na materialized view.
Consulta original
Consulta reescrita
SELECT t1.user_id, sum(t2.order_amount) AS total_amount FROM user_info AS t1 LEFT JOIN sale_order AS t2 ON t1.user_id=t2.user_id GROUP BY t1.user_id;SELECT user_id, total_amount FROM mv;
Exemplo 5: Reescrita com cláusula UNION ALL
-
Crie uma materialized view.
CREATE MATERIALIZED VIEW mv LIFECYCLE 7( user_id, tran_amount, tran_date ) AS SELECT user_id, tran_amount, tran_date FROM alipay_tran UNION ALL SELECT user_id, tran_amount, tran_date FROM unionpay_tran; -
A tabela a seguir mostra como uma consulta é reescrita com base na materialized view.
Consulta original
Consulta reescrita
SELECT user_id, tran_amount FROM alipay_tran UNION ALL SELECT user_id, tran_amount FROM unionpay_tran;SELECT user_id, tran_amount FROM mv;
Exemplo 6: Caso de uso
-
Cenário
Considere uma tabela de visitas a páginas chamada
visit_recordsque registra o ID da página, o ID do usuário e o horário de cada visita. Uma tarefa frequente de análise é contar o número de visitas para diferentes páginas.Nessa situação, crie uma materialized view em
visit_recordsque agrupe por ID da página e conte as visitas de cada página. Em seguida, execute consultas subsequentes nessa materialized view.A estrutura de
visit_recordsé a seguinte:+------------------------------------------------------------------------------------+ | Field | Type | Label | Comment | +------------------------------------------------------------------------------------+ | page_id | string | | | | user_id | string | | | | visit_time | string | | | +------------------------------------------------------------------------------------+ -
Crie uma materialized view.
-- Create a materialized view for the visit_records table that groups by page ID and counts the visits for each page. CREATE MATERIALIZED VIEW count_mv AS SELECT page_id, count(*) FROM visit_records GROUP BY page_id; -
Execute a seguinte consulta:
SET odps.sql.materialized.view.enable.auto.rewriting=true; SELECT page_id, count(*) FROM visit_records GROUP BY page_id;Ao executar essa instrução de consulta, o MaxCompute corresponde automaticamente à materialized view
count_mve lê os dados pré-agregados decount_mv. -
Para verificar se a consulta foi reescrita usando a materialized view, execute o seguinte comando
EXPLAIN:EXPLAIN SELECT page_id, count(*) FROM visit_records GROUP BY page_id;O resultado retornado é:
job0 is root job In Job job0: root Tasks: M1 In Task M1: Data source: doc_test_dev.count_mv TS: doc_test_dev.count_mv FS: output: Screen schema: page_id (string) _c1 (bigint) OKO campo
Data sourceno resultado retornado mostra que a tabela lida pela consulta é acount_mvdo projetodoc_test_dev. Isso indica que a materialized view está ativa e a reescrita da consulta foi bem-sucedida.
Documentos relacionados
Para mais informações sobre operações de materialized views, consulte Materialized view operations.
Para mais detalhes sobre o recurso de atualização agendada para materialized views, consulte Scheduled updates for materialized views.