A reescrita de consulta permite que o AnalyticDB for MySQL redirecione automaticamente as consultas para visualizações materializadas, sem exigir alterações no SQL. Quando uma consulta corresponde a uma visualização materializada, o mecanismo lê resultados pré-computados em vez de examinar as tabelas base, o que reduz significativamente a latência.
Pré-requisitos
-
Um cluster do AnalyticDB for MySQL deve executar a versão V3.1.4.0 ou posterior.
NotaPara verificar a versão secundária de um cluster Data Lakehouse Edition, execute
SELECT adb_version();. Para atualizar a versão secundária, entre em contato com o suporte técnico.Para visualizar e atualizar a versão secundária de um cluster Data Warehouse Edition, consulte Upgrade minor version.
-
O uso de visualizações materializadas exige as seguintes permissões:
Permissão CREATE no banco de dados onde reside a visualização materializada.
Permissão SELECT nas colunas relevantes ou em todas as tabelas base da visualização materializada.
-
Para criar uma visualização materializada com atualização automática, também são necessárias estas duas permissões:
Permissão para conectar-se ao AnalyticDB for MySQL a partir de qualquer endereço IP (ou seja,
'%').Permissão INSERT na visualização materializada ou em todas as tabelas do banco de dados onde ela reside. Caso contrário, não será possível atualizar os dados da visualização materializada.
Como funciona
O AnalyticDB for MySQL compara cada consulta recebida com todas as visualizações materializadas que têm a reescrita de consulta ativada. Se houver correspondência, o mecanismo reescreve a consulta para ler da visualização materializada em vez das tabelas base. Duas estratégias de correspondência são utilizadas, aplicadas na seguinte ordem:
Reescrita por correspondência exata: ocorre quando a estrutura da consulta é idêntica à definição da visualização materializada. Esta é a estratégia mais simples e com menos restrições.
Reescrita avançada de consulta: aplicada quando as estruturas diferem. O mecanismo utiliza regras de reescrita (FILTER, JOIN, AGGREGATION, AGGREGATION ROLLUP, SUBQUERIES, QUERY PARTIAL, UNION) para determinar se a visualização materializada contém dados suficientes para responder à consulta total ou parcialmente. Subconsultas diferentes na mesma instrução podem corresponder a visualizações materializadas distintas.
Todas as reescritas de consulta operam no nível STALE_TOLERATED: o mecanismo reescreve a consulta mesmo que a visualização materializada contenha dados desatualizados ainda não sincronizados com as tabelas base. Isso maximiza a cobertura da reescrita, mas significa que os resultados podem não refletir as inserções ou atualizações mais recentes. Atualize suas visualizações materializadas antes de executar consultas sensíveis à latência. Para obter detalhes, consulte Configure full refresh for materialized views.
Ativar a reescrita de consulta
Ative a reescrita de consulta de uma das duas maneiras abaixo:
No momento da criação, inclua a cláusula
ENABLE QUERY REWRITEna instruçãoCREATE MATERIALIZED VIEW. Consulte Create a materialized view — Parameters.-
Após a criação, execute:
ALTER MATERIALIZED VIEW <mv_name> ENABLE QUERY REWRITE;Consulte Gerencie visualizações materializadas.
Desativar a reescrita de consulta
Desative a reescrita de consulta de uma das duas maneiras abaixo:
-
Para uma visualização materializada específica:
ALTER MATERIALIZED VIEW <mv_name> DISABLE QUERY REWRITE; -
Para uma consulta específica, adicione uma dica antes da instrução
SELECT:/*+MV_QUERY_REWRITE_ENABLED=false*/ SELECT ...
Verificar se a reescrita de consulta está ativa
Após ativar a reescrita de consulta, use EXPLAIN para confirmar se o mecanismo está lendo da visualização materializada.
Exemplo
-
Crie uma visualização materializada com a reescrita de consulta ativada.
CREATE MATERIALIZED VIEW adb_mv REFRESH START WITH now() + interval 1 day ENABLE QUERY REWRITE AS SELECT course_id, course_name, max(course_grade) AS max_grade FROM tb_courses; -
Depois de ativar a reescrita de consulta, execute
EXPLAINna consulta.EXPLAIN SELECT course_id, course_name, max(course_grade) AS max_grade FROM tb_courses; -
Verifique o plano de execução. Quando a reescrita de consulta está ativa, a linha
TableScanmostra o nome da visualização materializada (adb_mv), e não o da tabela base (tb_courses).+---------------+ | Plan Summary | +---------------+ 1- Output[ Query plan ] {Est rowCount: 1.0} 2 -> Exchange[GATHER] {Est rowCount: 1.0} 3 - TableScan {table: adb_mv, Est rowCount: 1.0}Se o plano ainda mostrar
TableScan {table: tb_courses, ...}, a reescrita de consulta não foi ativada. Consulte a seção Solução de problemas.
Escopo da reescrita
Os exemplos a seguir demonstram cada regra de reescrita suportada pelo método de reescrita avançada de consulta. Todos os exemplos usam as mesmas quatro tabelas:
CREATE TABLE part (
partkey INTEGER NOT NULL,
name VARCHAR(55) NOT NULL,
type VARCHAR(25) NOT NULL
);
CREATE TABLE lineitem (
orderkey BIGINT,
partkey BIGINT NOT NULL,
suppkey BIGINT NOT NULL,
extendedprice DOUBLE NOT NULL,
discount DOUBLE NOT NULL,
returnflag CHAR(1) NOT NULL,
linestatus CHAR(1) NOT NULL,
shipdate DATE NOT NULL,
shipmode VARCHAR(25) NOT NULL,
commitdate DATE NOT NULL,
receiptdate DATE NOT NULL
);
CREATE TABLE orders (
orderkey BIGINT PRIMARY KEY,
custkey BIGINT NOT NULL,
orderstatus VARCHAR(1) NOT NULL,
totalprice DOUBLE NOT NULL,
orderdate DATE NOT NULL
);
CREATE TABLE partsupp (
partkey INTEGER NOT NULL PRIMARY KEY,
suppkey INTEGER NOT NULL,
availqty INTEGER NOT NULL,
supplycost DECIMAL(15,2) NOT NULL
);
Reescrita por correspondência exata
Quando a estrutura da consulta é idêntica à definição da visualização materializada, o mecanismo reescreve a consulta diretamente.
Consulta
SELECT
l.returnflag,
l.linestatus,
SUM(l.extendedprice * (1 - l.discount)),
COUNT(*) AS count_order
FROM lineitem AS l
GROUP BY l.returnflag, l.linestatus;
Visualização materializada
CREATE MATERIALIZED VIEW mv0
REFRESH NEXT now() + interval 1 day
ENABLE QUERY REWRITE
AS
SELECT
l.returnflag,
l.linestatus,
SUM(l.extendedprice * (1 - l.discount)) AS sum_disc_price,
COUNT(*) AS count_order
FROM lineitem AS l
GROUP BY l.returnflag, l.linestatus;
Consulta reescrita
SELECT returnflag, linestatus, sum_disc_price, count_order
FROM mv0;
Reescrita avançada de consulta
FILTER
Quando o predicado da consulta é mais restritivo que o da visualização materializada, o mecanismo adiciona uma cláusula WHERE à varredura da visualização materializada para aplicar o filtro ausente. Se uma expressão na consulta não existir na visualização materializada, o mecanismo também tentará calcular essa expressão a partir da visualização.
Consulta
SELECT
l.shipmode,
l.extendedprice * (1 - l.discount) AS disc_price
FROM orders AS o, lineitem AS l
WHERE o.orderkey = l.orderkey
AND l.shipmode IN ('REG AIR', 'TRUCK')
AND l.commitdate < l.receiptdate
AND l.shipdate < l.commitdate;
Visualização materializada
CREATE MATERIALIZED VIEW mv1
REFRESH NEXT now() + interval 1 day
ENABLE QUERY REWRITE
AS
SELECT
l.shipmode,
l.extendedprice,
l.discount
FROM orders AS o, lineitem AS l
WHERE o.orderkey = l.orderkey
AND l.commitdate < l.receiptdate
AND l.shipdate < l.commitdate;
Consulta reescrita
SELECT
shipmode,
extendedprice * (1 - discount) AS disc_price,
discount
FROM mv1
WHERE shipmode IN ('REG AIR', 'TRUCK');
JOIN
Quando a consulta e a visualização materializada possuem relações de junção diferentes, o mecanismo deriva a junção necessária a partir da visualização materializada. Por exemplo, uma visualização materializada com outer join pode atender a uma consulta que requer inner join filtrando as linhas nulas.
Tipos de junção suportados: inner join, outer join, left join e right join.
Consulta
SELECT
p.type,
p.partkey,
ps.suppkey
FROM part AS p, partsupp AS ps
WHERE p.partkey = ps.partkey
AND p.type NOT LIKE 'MEDIUM POLISHED%';
Visualização materializada
CREATE MATERIALIZED VIEW mv2
REFRESH NEXT now() + INTERVAL 1 day
ENABLE QUERY REWRITE
AS
SELECT
p.type,
p.partkey,
ps.suppkey
FROM partsupp AS ps
INNER JOIN part AS p ON p.partkey = ps.partkey
WHERE p.type NOT LIKE 'MEDIUM POLISHED%';
Consulta reescrita
SELECT type, partkey, suppkey
FROM mv2;
AGGREGATION
Quando a consulta ou a visualização materializada usa cláusulas GROUP BY ou funções de agregação diferentes, o mecanismo constrói a mesma função de agregação a partir da visualização materializada usando a regra AGGREGATION.
Consulta
SELECT
l.returnflag,
l.linestatus,
SUM(l.extendedprice * (1 - l.discount)) AS sum_disc_price
FROM lineitem AS l
GROUP BY l.returnflag, l.linestatus;
Visualização materializada
CREATE MATERIALIZED VIEW mv3
REFRESH NEXT now() + INTERVAL 1 day
ENABLE QUERY REWRITE
AS
SELECT
l.returnflag,
l.linestatus,
SUM(l.extendedprice * (1 - l.discount)) AS sum_disc_price,
COUNT(*) AS count_order
FROM lineitem AS l
GROUP BY l.returnflag, l.linestatus;
Consulta reescrita
SELECT returnflag, linestatus, sum_disc_price, count_order
FROM mv3;
AGGREGATION ROLLUP
Quando a consulta agrupa por um subconjunto dos campos GROUP BY da visualização materializada, o mecanismo consolida os agregados pré-computados.
Consulta
SELECT
l.returnflag,
SUM(l.extendedprice * (1 - l.discount)) AS sum_disc_price,
COUNT(*) AS count_order
FROM lineitem AS l
WHERE l.returnflag = 'R'
GROUP BY l.returnflag;
Visualização materializada
CREATE MATERIALIZED VIEW mv4
REFRESH NEXT now() + INTERVAL 1 day
ENABLE QUERY REWRITE
AS
SELECT
l.returnflag,
l.linestatus,
SUM(l.extendedprice * (1 - l.discount)) AS sum_disc_price,
COUNT(*) AS count_order
FROM lineitem AS l
GROUP BY l.returnflag, l.linestatus;
Consulta reescrita
SELECT
returnflag,
linestatus,
sum_disc_price,
count_order
FROM mv4
WHERE returnflag = 'R'
GROUP BY returnflag;
SUBQUERIES
Quando a consulta usa uma subconsulta no lugar de uma tabela base, o mecanismo verifica se a visualização materializada cobre toda a tabela e insere o filtro da subconsulta na varredura reescrita.
Consulta
SELECT
p.type,
p.partkey,
ps.suppkey
FROM part AS p,
(SELECT * FROM partsupp WHERE suppkey > 10) ps
WHERE p.partkey = ps.partkey;
Visualização materializada
CREATE MATERIALIZED VIEW mv5
REFRESH NEXT now() + INTERVAL 1 day
ENABLE QUERY REWRITE
AS
SELECT
p.type,
p.partkey,
ps.suppkey
FROM part AS p, partsupp AS ps
WHERE p.partkey = ps.partkey;
Consulta reescrita
SELECT type, partkey, suppkey
FROM mv5
WHERE suppkey > 10;
QUERY PARTIAL
Quando a consulta referencia uma tabela não coberta pela visualização materializada, o mecanismo junta a visualização materializada à tabela ausente.
Consulta
SELECT
p.type,
p.partkey,
ps.suppkey
FROM part AS p, partsupp AS ps
WHERE p.partkey = ps.partkey
AND p.type NOT LIKE 'MEDIUM POLISHED%';
Visualização materializada
CREATE MATERIALIZED VIEW mv6
REFRESH NEXT now() + INTERVAL 1 day
ENABLE QUERY REWRITE
AS
SELECT
p.type,
p.partkey
FROM part AS p
WHERE p.type NOT LIKE 'MEDIUM POLISHED%';
Consulta reescrita
SELECT
mv6.type,
mv6.partkey,
ps.suppkey
FROM mv6, partsupp AS ps
WHERE mv6.partkey = ps.partkey;
UNION
Quando a visualização materializada cobre apenas parte do intervalo de datas ou valores da consulta, o mecanismo recupera a parte coberta da visualização materializada e busca as linhas restantes diretamente da tabela base, combinando depois os resultados com UNION ALL.
Consulta
SELECT
l.linestatus,
COUNT(*) AS count_order
FROM lineitem AS l
WHERE l.shipdate >= DATE '1998-01-01'
GROUP BY l.linestatus;
Visualização materializada (cobre apenas shipdate >= 2000-01-01)
CREATE MATERIALIZED VIEW mv7
REFRESH NEXT now() + interval 1 day
ENABLE QUERY REWRITE
AS
SELECT
l.linestatus,
COUNT(*) AS count_order
FROM lineitem AS l
WHERE l.shipdate >= DATE '2000-01-01'
GROUP BY l.linestatus;
Consulta reescrita
SELECT linestatus, count_order
FROM (
SELECT linestatus, count_order
FROM mv7
UNION ALL
SELECT
l.linestatus,
COUNT(*) AS count_order
FROM lineitem AS l
WHERE l.shipdate >= DATE '1998-01-01' AND l.shipdate < DATE '1998-01-01'
GROUP BY l.linestatus
)
GROUP BY linestatus;
Limitações
Reescrita por correspondência exata
O método de reescrita por correspondência exata não é ativado se a visualização materializada contiver:
Funções não determinísticas:
NOW,CURRENT_TIMESTAMP,RANDOMFunções definidas pelo usuário (UDFs)
Reescrita avançada de consulta
O método de reescrita avançada de consulta não é ativado se a visualização materializada contiver qualquer um dos itens a seguir:
Cláusula
ORDER BY,LIMITouOFFSETCláusula
UNIONouUNION ALLGROUPING SETS,CUBEouROLLUPem uma cláusulaGROUP BYFunções de janela
FULL OUTER JOINTabelas do sistema
Subconsultas correlacionadas
Funções não determinísticas:
NOW,CURRENT_TIMESTAMP,RANDOMUDFs
Cláusula
HAVINGSELF JOIN
Tipos de instrução onde a reescrita de consulta nunca é ativada
A reescrita de consulta não se aplica a consultas incorporadas nos seguintes tipos de instrução, independentemente da definição da visualização materializada:
CREATE TABLE AS SELECTINSERT INTO SELECTINSERT OVERWRITE SELECTREPLACE INTO SELECTDELETEouUPDATE
Consultas de tabela única sem filtros ou agregações
A reescrita de consulta não é ativada para consultas de tabela única sem condições de filtro nem funções de agregação.
Solução de problemas
A reescrita de consulta não está sendo ativada após a criação de uma visualização materializada.
Comece pelas causas mais comuns:
A reescrita de consulta não está ativada na visualização materializada. Execute
ALTER MATERIALIZED VIEW <mv_name> ENABLE QUERY REWRITE;e tente novamente.A visualização materializada atingiu uma limitação. Revise a seção Limitations e verifique se a definição da sua visualização materializada inclui alguma cláusula ou função não suportada.
-
Falta a permissão SELECT na visualização materializada. Conceda a permissão necessária à conta que executa a consulta:
GRANT SELECT ON <database>.<mv_name> TO '<account>';Para obter detalhes, consulte a seção Required permissions do tópico Consultar dados de uma visualização materializada.