Aumente o throughput e reduza a latência das implantações de Flink SQL ajustando recursos, ativando otimizações de agregação e reescrevendo padrões de SQL.
Definir parâmetros de base para throughput
Adicione os seguintes parâmetros ao campo Other Configuration na seção Parameters da aba Configuration. Essas configurações melhoram o throughput e reduzem problemas de hotspot.Configure custom deployment parameters.
execution.checkpointing.interval: 180s
table.exec.state.ttl: 129600000
table.exec.mini-batch.enabled: true
table.exec.mini-batch.allow-latency: 5s
table.optimizer.distinct-agg.split.enabled: true
|
Parâmetro |
Descrição |
|
|
Intervalo de checkpoint. O valor |
|
|
Tipo de backend de estado. |
|
|
Tempo de vida (TTL) dos dados de estado, em milissegundos. |
|
|
Ativa a agregação miniBatch. |
|
|
Latência máxima antes que um mini-batch seja acionado. |
|
|
Número máximo de registros por mini-batch. O VVR otimiza esse valor automaticamente — deixe sem configuração na maioria dos casos.Key parameters. |
|
|
Ativa a otimização PartialFinal para COUNT DISTINCT. |
Dimensionar recursos da implantação
A Ververica Platform (VVP) limita a CPU do JobManager e do TaskManager aos valores configurados. Aumente esses limites quando as implantações estiverem com restrição de recursos.
Dimensionar recursos do JobManager
Para implantações paralelas, aumente os recursos do JobManager na seção Resources da aba Configuration. Por exemplo:
Job Manager CPU: 4
Job Manager Memory: 8 GiB
Dimensionar recursos do TaskManager
Em topologias complexas, aumente os recursos do TaskManager na seção Resources da aba Configuration. Por exemplo:
Task Manager CPU: 2
Task Manager Memory: 4 GiB
Mantenha taskmanager.numberOfTaskSlots no valor padrão de 1.
Otimizar agregação de grupo
Por padrão, o operador de agregação de grupo processa os registros individualmente: lê o acumulador do estado, atualiza-o, grava-o de volta e repete o processo. Esse padrão por registro aumenta a sobrecarga do backend de estado — especialmente com RocksDB — e piora em cenários com hotspots de dados.
Ativar miniBatch
O miniBatch armazena em buffer os registros recebidos e os processa em conjunto, reduzindo os acessos ao estado por lote. Isso melhora o throughput ao custo de uma latência ligeiramente maior. O recurso miniBatch aciona o processamento de micro-lotes com base em mensagens de evento inseridas na source em um intervalo especificado.
Quando usar: Cenários de agregação de dados que não exigem latência ultrabaixa.
Como ativar: Adicione o seguinte ao campo Other Configuration na seção Parameters da aba Configuration. Configure custom deployment parameters.
table.exec.mini-batch.enabled: true
table.exec.mini-batch.allow-latency: 5s
|
Parâmetro |
Descrição |
|
|
Defina como |
|
|
Latência máxima antes que um mini-batch seja acionado. |
|
|
Número máximo de registros por mini-batch. Deixe sem configuração — o VVR otimiza esse valor automaticamente. Key parameters. |
Ativar LocalGlobal
O LocalGlobal divide a agregação em duas fases — pré-agregação local em cada nó upstream e, em seguida, agregação global — semelhante ao combine e reduce do MapReduce. A agregação local pré-filtra dados de hotspot, reduzindo o volume que chega à fase global.
Quando usar: Funções de agregação comuns como SUM, COUNT, MAX, MIN e AVG com problemas de hotspot de dados.
Pré-requisitos:
O miniBatch deve estar ativado. O LocalGlobal usa o intervalo do mini-batch para determinar quantos registros acumular antes da agregação local.
A função de agregação deve implementar o método
merge(AggregateFunction).
Status: Ativado por padrão quando o miniBatch está ativo.
Verificar: Verifique se a topologia final contém um nó GlobalGroupAggregate ou LocalGroupAggregate.
Ativar PartialFinal para COUNT DISTINCT
O LocalGlobal é menos eficaz para COUNT DISTINCT porque a agregação local não consegue remover chaves distintas duplicadas. O PartialFinal resolve isso dividindo a agregação em duas camadas: a primeira dispersa os dados pelo hash da chave distinta, e a segunda realiza a agregação final.
Quando usar: Consultas COUNT DISTINCT com grandes volumes de dados em que o desempenho da agregação é um gargalo.
Como ativar: Adicione o seguinte ao campo Other Configuration. Configure custom deployment parameters.
table.optimizer.distinct-agg.split.enabled: true
Limitações:
Não é possível usar o PartialFinal em SQL que contenha funções de agregação definidas pelo usuário (UDAFs).
Ative apenas para grandes volumes de dados. O PartialFinal introduz um shuffle de rede adicional.
Verificar: Confirme se a agregação de uma camada mudou para agregação de duas camadas na topologia final.
Usar AGG WITH FILTER em vez de CASE WHEN
Ao calcular COUNT DISTINCT no mesmo campo sob condições diferentes, use a cláusula FILTER em vez de CASE WHEN. O otimizador reconhece argumentos de filtro diferentes na mesma chave distinta e usa uma única instância de estado compartilhada, reduzindo o acesso ao estado e seu tamanho. Testes de desempenho mostram uma melhoria de 2x em relação ao CASE WHEN.
Antes (menos eficiente):
COUNT(DISTINCT visitor_id) AS uv_total,
COUNT(DISTINCT CASE WHEN is_wireless = 'y' THEN visitor_id ELSE NULL END) AS uv_wireless
Depois (desempenho 2x superior):
COUNT(DISTINCT visitor_id) AS uv_total,
COUNT(DISTINCT visitor_id) FILTER (WHERE is_wireless = 'y') AS uv_wireless
Usar Delta Aggregation (agregação sem estado)
A Delta Aggregation é suportada apenas em implantações do Realtime Compute for Apache Flink que usam VVR 11.8 ou posterior.
A Delta Aggregation fornece agregação sem estado para agregação de grupo sem janela em streaming. Diferente da agregação de grupo regular, que mantém continuamente um acumulador de agregação para cada grupo no estado do Flink, a Delta Aggregation responde a uma alteração de dados usando a chave de agrupamento para buscar assincronamente os registros de detalhe atuais do grupo e recalcular o resultado agregado a partir desses registros.
Como resultado, a quantidade de estado de agregação no lado do Flink não depende mais do número histórico de grupos. A implantação não precisa expandir continuamente seu estado de agregação à medida que o número de grupos cresce. Isso reduz a quantidade de dados persistidos em checkpoints, diminui o tempo de recuperação e estabiliza o uso de recursos em implantações de agregação de grupo em grande escala.
Casos de uso
A Delta Aggregation busca assincronamente os registros de detalhe atuais de um grupo e recalcula os resultados agregados sob demanda. Utilize-a para implantações que possuem um ou mais dos seguintes requisitos:
Após alterações na lógica da implantação, a agregação de grupo regular exige iniciar a implantação de streaming sem estado e reconstruí-lo. Com a Delta Aggregation, execute primeiro uma implantação em lote sem estado para atualizar a tabela de resultados e, em seguida, inicie a implantação de streaming com estado. Isso aproveita o alto throughput do processamento em lote para acelerar o backfill de resultados e a recuperação da implantação.
Reduzir a latência de checkpoint e a contrapressão de processamento de estado quando o estado do grupo for grande.
Reduzir significativamente o estado de agregação restaurado na reinicialização da implantação, encurtando o tempo de recuperação.
Diminuir os recursos de computação e armazenamento usados pelo estado de agregação e reduzir os custos de unidade de computação (CU).
Compartilhar o estado de detalhe atual na tabela de origem quando várias implantações agregam os mesmos dados de detalhe.
Consultar registros de detalhe atuais diretamente da tabela de origem para validar resultados agregados e solucionar problemas.
Limites
Estrutura da consulta
Há suporte apenas para agregação de grupo sem janela de nível único em implantações de streaming. Não há suporte para agregação de janela nem agregação em cascata.
O
GROUP BYdeve conter um conjunto de colunas que mapeiam diretamente para campos da tabela de origem e deve incluir a chave primária completa da tabela de origem ou um índice consultável.Não há suporte para expressões não determinísticas como
PROCTIME()eRAND().
Tabelas upstream e downstream
O conector de origem deve suportar tanto leituras em streaming quanto buscas assíncronas.
A tabela de origem não pode definir uma watermark.
Os registros de alteração que a Delta Aggregation envia para downstream contêm apenas
UPDATE_AFTER(+U) eDELETE(-D). Eles não contêmUPDATE_BEFORE(-U).
Funções de agregação
As seguintes funções são suportadas:
SUM,COUNT,AVG,MIN,MAX,LISTAGG,FIRST_VALUEeLAST_VALUE.Não há suporte para agregação
DISTINCT, agregação com cláusulaFILTER, funções de agregação definidas pelo usuário (UDAFs), funções de agregação Python e outras funções de agregação não listadas.
Exemplo
Uma plataforma de e-commerce precisa manter a contagem de registros e o valor atuais para um grande número de pedidos. Ela grava os resultados em uma tabela de resumo para que um service de consulta de pedidos possa recuperá-los diretamente por comerciante e pedido. O exemplo a seguir usa a chave primária completa da tabela de origem como chave de busca.
-
Etapa 1: Crie as tabelas de origem e de resultados.
A tabela de origem deve suportar tanto leituras em streaming quanto buscas assíncronas.
CREATE TABLE orders ( merchant_id BIGINT, -- Merchant ID order_id BIGINT, -- Order ID amount DECIMAL(18, 2), -- Current order amount PRIMARY KEY (merchant_id, order_id) NOT ENFORCED ) WITH ( 'connector' = '<source-connector>', '<source-option>' = '<source-option-value>' );Use todos os campos de agrupamento como chave primária da tabela de resultados.
CREATE TABLE order_current_summary ( merchant_id BIGINT, -- Merchant ID order_id BIGINT, -- Order ID current_record_count BIGINT, -- Current valid record count total_amount DECIMAL(38, 2), -- Current total amount PRIMARY KEY (merchant_id, order_id) NOT ENFORCED ) WITH ( 'connector' = '<sink-connector>', '<sink-option>' = '<sink-option-value>' ); -
Etapa 2: Execute a implantação de agregação.
Ative a Delta Aggregation antes da instrução
INSERT INTO:SET 'table.optimizer.delta-agg.strategy' = 'EVENTUAL';Use SQL de agregação de grupo padrão. Nenhuma sintaxe dedicada é necessária:
INSERT INTO order_current_summary SELECT merchant_id, order_id, COUNT(*) AS current_record_count, SUM(amount) AS total_amount FROM orders GROUP BY merchant_id, order_id;Neste exemplo,
GROUP BY (merchant_id, order_id)cobre totalmente a chave primária da tabela de origem, e a chave primária da tabela de resultados corresponde aos campos de agrupamento. -
Etapa 3: Verifique o plano de execução.
Revise o plano de execução de SQL antes de enviar a implantação. Um nó
DeltaAggregateindica que a Delta Aggregation está ativada. Exemplo:DeltaAggregate( groupBy=[merchant_id, order_id], lookupKeys=[merchant_id, order_id] )
Ajuste opcional
Execute primeiro a implantação com as configurações padrão. Em seguida, ajuste parâmetros individuais com base no desempenho da busca e no throughput da implantação. Coloque cada uma das seguintes instruções SET antes de sua instrução INSERT INTO correspondente.
Selecionar uma estratégia de ativação
O parâmetro table.optimizer.delta-agg.strategy suporta os seguintes valores:
|
Valor |
Descrição |
|
|
Força a Delta Aggregation. Se a consulta não atender aos requisitos, um erro será retornado quando o plano de execução for gerado. |
|
|
Tenta usar a Delta Aggregation. Se a consulta não atender aos requisitos, o engine reverte para a agregação de grupo regular. |
|
|
Desativa a Delta Aggregation. Este é o valor padrão. |
Ajustar parâmetros de busca assíncrona
Use os seguintes parâmetros para ajustar a concorrência e o tempo limite da busca assíncrona:
SET 'table.exec.async-lookup.buffer-capacity' = '100';
SET 'table.exec.async-lookup.timeout' = '3 min';
|
Parâmetro |
Padrão |
Descrição |
|
|
|
Número de solicitações de busca assíncrona que cada subtarefa paralela pode executar simultaneamente. Aumente este valor para elevar a concorrência da busca assíncrona. |
|
|
|
Período de tempo limite para uma única operação assíncrona. |
Para obter mais informações sobre o ajuste de busca assíncrona, consulte Instruções JOIN de tabela de dimensão.
Ativar miniBatch Delta Aggregation
Tanto a Delta Aggregation quanto a Group Aggregation suportam a otimização miniBatch. Para a Delta Aggregation, o miniBatch combina alterações que possuem a mesma chave de agrupamento dentro de um lote. Isso limita cada chave de agrupamento a no máximo uma busca por lote e reduz o número de buscas na tabela de origem.
Use as seguintes configurações para ativar o miniBatch para Delta Aggregation:
SET 'table.exec.mini-batch.enabled' = 'true';
SET 'table.exec.mini-batch.allow-latency' = '10s';
SET 'table.exec.mini-batch.size' = '1000';
Com essas configurações, cada subtarefa paralela aciona o processamento após receber 1.000 registros de entrada ou após o lote aguardar por 10 segundos.
Para obter mais informações sobre a otimização miniBatch e seus parâmetros, consulte a seção anterior, Ativar miniBatch.
Ativar o cache da Delta Aggregation
Se a mesma chave de agrupamento for atualizada repetidamente, ative o cache para reutilizar registros de detalhe de grupo recuperados anteriormente. Quando ocorre um acerto de cache, o Flink atualiza os registros em cache com a alteração de entrada e recalcula o resultado agregado diretamente sem outra busca.
Quando o cache está ativado, a tabela de origem deve ter uma chave primária. O Flink usa a chave primária da tabela de origem para identificar e atualizar registros de detalhe no cache. O valor de table.exec.delta-agg.cache-size deve ser maior que 0.
SET 'table.exec.delta-agg.cache-enabled' = 'true';
SET 'table.exec.delta-agg.cache-size' = '2000';
|
Parâmetro |
Padrão |
Descrição |
|
|
|
Especifica se deve ativar o cache da Delta Aggregation. |
|
|
|
Número máximo de chaves de agrupamento armazenadas em cache por cada subtarefa paralela da Delta Aggregation. Este parâmetro só tem efeito quando o cache está ativado. |
Relaxar validação de filtros de resultado agregado
A Delta Aggregation não envia registros -U para resultados agregados anteriores. Considere o filtro downstream HAVING SUM(amount) >= 100. Quando o SUM(amount) de um grupo muda de 120 para 80:
+U(..., 120) → Matches the condition and is written to the result table
+U(..., 80) → Does not match the condition and is filtered out
Como nenhum registro -U retrai o resultado anterior, o registro SUM(amount)=120 permanece na tabela de resultados. Para evitar esse problema, a Delta Aggregation exige que os filtros downstream referenciem apenas campos de chave única do resultado agregado, normalmente os campos GROUP BY.
Se um filtro referenciar um campo de chave não única, como SUM, a estratégia EVENTUAL retornará um erro e a estratégia AUTO reverterá para a agregação de grupo regular. Uma condição WHERE antes do GROUP BY não está sujeita a essa validação.
Se o seu negócio puder tolerar esse comportamento, use a seguinte configuração para ignorar a validação:
SET 'table.optimizer.delta-agg.ignore-non-unique-key-filter' = 'true';
|
Parâmetro |
Padrão |
Descrição |
|
|
|
Especifica se deve ignorar a validação de filtros de chave não única nos resultados da Delta Aggregation. |
Essa configuração ignora apenas a validação. Ela não altera o filtro na instrução SQL nem faz com que a Delta Aggregation gere registros -U. Portanto, o Flink não envia registros de retração para remover os resultados obsoletos descritos acima.
Otimizar joins
Separação de chave-valor para joins de dois fluxos
No VVR 6.0.1 e posterior, o engine infere automaticamente se deve ativar a separação de chave-valor para operadores JOIN de dois fluxos, melhorando o desempenho típico de join em mais de 40%.
Configure o parâmetro table.exec.join.kv-separate para controlar esse comportamento:
|
Valor |
Comportamento |
|
|
O engine ativa a separação de chave-valor automaticamente com base no estado do operador de join. Padrão. |
|
|
Força a ativação da separação de chave-valor. |
|
|
Força a desativação da separação de chave-valor. |
A separação de chave-valor só tem efeito no GeminiStateBackend.
Ativar miniBatch para joins
Por padrão, o operador de join regular processa os registros individualmente: busca o estado correspondente pela chave de join, atualiza o estado e gera os resultados. Esse padrão por registro aumenta a sobrecarga do backend de estado — especialmente com RocksDB — e pode causar amplificação severa de registros em joins em cascata.
O miniBatch para joins resolve isso com duas otimizações principais:
Compactação de registros: Compacta registros no buffer para reduzir o volume de dados antes do processo de join.
Supressão de saída: Suprime resultados intermediários redundantes durante o processamento em lote.
O miniBatch aciona o processamento quando a latência máxima permitida é atingida, o limite de tamanho do lote é alcançado ou ocorre um checkpoint.
Versão do VVR: 8.0.4 ou posterior.
Como ativar: Adicione o seguinte ao campo Other Configuration. Configure custom deployment parameters.
table.exec.mini-batch.enabled: true
table.exec.mini-batch.allow-latency: 5s
table.exec.stream.join.mini-batch-enabled: true
Mais indicado para: Outer joins em cascata com amplificação de mensagens. Operadores upstream usam colapso ou mesclagem de mensagens para suprimir a amplificação em operadores downstream. Por exemplo:
SELECT a.id AS a_id, a.a_content, B.id AS b_id, B.b_content
FROM a LEFT JOIN
(SELECT * FROM b
LEFT JOIN c ON b.prd_id = c.id) B
ON a.id = B.id
Otimizar consultas TopN
Algoritmos TopN
O algoritmo usado depende se o fluxo de dados de entrada é estático ou dinâmico:
|
Tipo de entrada |
Algoritmos disponíveis |
Observações |
|
Fluxos de dados estáticos (ex.: do Simple Log Service) |
AppendRank |
Única opção para fluxos estáticos. |
|
Fluxos de dados dinâmicos (ex.: de agregação ou join) |
UpdateFastRank, RetractRank |
UpdateFastRank é o ideal. RetractRank é o fallback. |
O nome do algoritmo aparece no nome do nó da topologia.
Alternar de RetractRank para UpdateFastRank
O UpdateFastRank exige todas as seguintes condições:
-
O fluxo de entrada não contém mensagens DELETE ou UPDATE_BEFORE. Verifique com EXPLAIN:
EXPLAIN CHANGELOG_MODE <query_statement_or_insert_statement_or_statement_set> O fluxo de entrada contém informações de chave primária (ex.: colunas usadas em uma cláusula GROUP BY).
Os campos ORDER BY são atualizados monotonamente na ordem oposta à classificação. Por exemplo, ORDER BY COUNT DESC, ORDER BY COUNT_DISTINCT DESC ou ORDER BY SUM(valor positivo) DESC.
Exemplo: Para ORDER BY SUM DESC, filtre por valores positivos para garantir a monotonicidade:
INSERT INTO print_test
SELECT
cate_id,
seller_id,
stat_date,
pay_ord_amt
FROM (
SELECT
*,
ROW_NUMBER() OVER (
-- The PARTITION BY columns must appear in the subquery's GROUP BY.
-- Include a time field to prevent disorder when state expires.
PARTITION BY cate_id, stat_date
ORDER BY pay_ord_amt DESC
) AS rownum
FROM (
SELECT
cate_id,
seller_id,
stat_date,
-- SUM is monotonically increasing because only positive values are included.
SUM(total_fee) FILTER (WHERE total_fee >= 0) AS pay_ord_amt
FROM random_test
WHERE total_fee >= 0
GROUP BY seller_id, stat_date, cate_id
) a
)
WHERE rownum <= 100;
Neste exemplo, a tabela random_test contém fluxos de dados estáticos. O resultado da agregação não contém mensagens DELETE ou UPDATE_BEFORE, portanto a monotonicidade é preservada.
Reduzir volume de saída
Não inclua rownum na saída SELECT final. Ordene os resultados no frontend para reduzir o volume de gravação no sink. Top-N.
Aumentar o tamanho do cache TopN
O TopN mantém um cache de estado para reduzir leituras em disco. Calcule a taxa de acerto do cache com esta fórmula:
cache_hit = cache_size * parallelism / top_n / partition_key_num
Exemplo: Com Top100, tamanho de cache padrão de 10.000 registros, paralelismo de 50 e 100.000 chaves de partição:
10,000 * 50 / 100 / 100,000 = 5% hit ratio
Uma taxa de acerto de 5% significa que a maioria das leituras vai para o disco, causando instabilidade nas métricas de state seek e degradando o desempenho. Aumente o tamanho do cache:
table.exec.rank.topn-cache-size: 200000
Com 200.000 entradas de cache:
200,000 * 50 / 100 / 100,000 = 100% hit ratio
Se a contagem de chaves de partição for grande, aumente também o tamanho do cache TopN e a memória heap. Configure a deployment.
Incluir um campo de tempo em PARTITION BY
Adicione um campo de tempo como day à cláusula PARTITION BY. Sem ele, os resultados do TopN ficam desordenados quando os dados de estado expiram devido ao TTL.
Deduplicar eficientemente
Fluxos de entrada frequentemente contêm duplicatas. O Realtime Compute for Apache Flink fornece duas políticas de deduplicação:
Deduplicate Keep FirstRow: Mantém o registro mais antigo por chave.
Deduplicate Keep LastRow: Mantém o registro mais recente por chave.
Sintaxe
A deduplicação é um caso especial de TopN. Use ROW_NUMBER() com uma cláusula OVER para atribuir um número de linha por partição e, em seguida, mantenha apenas rownum = 1:
SELECT *
FROM (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY col1[, col2..]
ORDER BY timeAttributeCol [ASC|DESC]) AS rownum
FROM table_name)
WHERE rownum = 1
|
Elemento |
Descrição |
|
|
Atribui um número de linha começando em 1 dentro de cada partição. |
|
|
Colunas que definem a chave de deduplicação. |
|
|
Uma coluna de atributo de tempo ( |
|
|
Retém apenas a primeira linha por partição. Também suporta |
Comportamento do atributo de tempo:
proctime(tempo de processamento): A deduplicação baseia-se no momento em que os registros são processados. Os resultados podem variar entre execuções.rowtime(tempo de evento): A deduplicação baseia-se no momento em que os registros foram produzidos. Os resultados são determinísticos.
Keep FirstRow
Mantém o primeiro registro por chave de deduplicação. O estado armazena apenas dados da chave primária, tornando o acesso ao estado altamente eficiente.
SELECT *
FROM (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY b ORDER BY proctime) AS rowNum
FROM T
)
WHERE rowNum = 1
Deduplica a tabela T pela coluna b, mantendo o registro mais antigo por tempo de processamento. Em vez de declarar um atributo proctime, chame a função PROCTIME().
Keep LastRow
Mantém o registro mais recente por chave de deduplicação. Isso tem um desempenho ligeiramente superior à função LAST_VALUE.
SELECT *
FROM (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY b, d ORDER BY rowtime DESC) AS rowNum
FROM T
)
WHERE rowNum = 1
Deduplica a tabela T pelas colunas b e d, mantendo o registro mais recente por tempo de evento.
Usar funções integradas eficientemente
Preferir funções integradas em vez de UDFs
As funções integradas são otimizadas para serialização, desserialização e operações no nível de byte. Substitua UDFs por equivalentes integrados sempre que possível.
Usar delimitadores de caractere único em KEYVALUE
A função KEYVALUE(content, keyValueSplit, keySplit, keyName) executa cerca de 30% mais rápido quando keyValueSplit e keySplit são caracteres únicos, como : ou ,. Com delimitadores de caractere único, o engine busca a chave alvo diretamente nos dados binários sem analisar toda a entrada.
Padrões do operador LIKE
|
Padrão |
Correspondências |
Exemplo |
|
|
Começa com |
|
|
|
Termina com |
|
|
|
Contém |
|
|
|
Correspondência exata (equivalente a |
|
Escapar underscores: O underscore (_) é um curinga de caractere único em SQL. Para corresponder a um underscore literal, use um caractere de escape:
LIKE '%seller/_id%' ESCAPE '/'
Sem o escape, LIKE '%seller_id%' também corresponde a seller#id, sellerxid, seller1id e outras strings não intencionais.
Evitar expressões regulares
Expressões regulares podem ser 100x mais lentas que operações aritméticas e podem entrar em loops infinitos em casos extremos, bloqueando implantações. Use LIKE sempre que possível.
Para casos que exigem expressões regulares, consulte REGEXP e REGEXP_REPLACE.
SQL hints
SQL hints influenciam o plano de execução do otimizador, anexam metadados ou estatísticas e configuram Dynamic Table Options por tabela. SQL hints.
Sintaxe
A sintaxe segue o Apache Calcite SQL:
SELECT /*+ hint [, hint ] */ ...
-- Where:
-- hint: hintName(hintOption [, hintOption]*)
-- hintOption: simpleIdentifier | numericLiteral | stringLiteral
Join hints
Query hints modificam o plano de execução dentro do bloco de consulta atual. Atualmente, o Flink suporta apenas join hints, tanto para dimension table joins quanto para regular joins.