Suporte SQL e Estratégias Alternativas em Ambientes PostgreSQL Distribuídos com Citus

O Citus estende o PostgreSQL para oferecer funcionalidades distribuídas, mantendo compatibilidade estrutural com o ecossistema PostgreSQL. Isso permite que ferramentas e recursos nativos do PostgreSQL sejam utilizados em tabelas distribuídas criadas pelo Citus.

Consultas executadas em um único nó de trabalho possuem 100% de cobertura SQL, sendo comuns em aplicações multilocatário que acessam dados de um inquilino específico.

Para consultas que envolvem paralelismo entre nós, a maioria dos recursos SQL é suportada. No entanto, operações que combinam dados de múltiplos nós apresentam restrições em certas funcionalidades.

Limitações em consultas entre nós:

  • SELECT … FOR UPDATE e TABLESAMPLE funcionam apenas em consultas com um único fragmento.
  • Subconsultas correlacionadas são suportadas apanas quando a correlação está na coluna de distribuição.
  • Outer joins entre tabelas distribuídas exigem junção na coluna de distribuição.
  • Outer joins entre tabelas distribuídas e tabelas de referência ou locais só são permitidos quando a tabela distribuída está à esquerda.
  • CTEs recursivos e grouping sets restringem-se a consultas de único fragmento.

Consulte a documentação oficial do PostgreSQL para detalhes sobre seus comandos SQL, que podem ser utilizados diretamente com o Citus.

Abordagens para Contornar Restrições

Antes de buscar alternativas, avalie se o Citus é adequado para seu caso de uso, como análises em tempo real ou sistemas multilocatário. Mesmo em consultas entre nós, a maioria das operações SQL é permiitda. Algumas limitações possuem soluções criativas.

Uso de CTEs para Flexibilidade

Quando uma consulta SQL não é suportada diretamente, CTEs podem ser empregados para converter a operação em uma consulta roteável, utilizando a técnica de pull-push.

Exemplo com erro de sintaxe original:

SELECT * FROM tabela_referencia 
LEFT JOIN tabela_distribuida USING (identificador) 
WHERE tabela_distribuida.valor > 50;

Transformando com CTE:

WITH dados_filtrados AS (
  SELECT * FROM tabela_distribuida WHERE valor > 50
)
SELECT * FROM tabela_referencia 
LEFT JOIN dados_filtrados USING (identificador);

Note que o coordenador transmitirá os resultados do CTE para todos os workers necessários. Para minimizar a sobrecarga de rede, aplique filtros e limites específicos na subconsulta interna.

Tabelas Temporárias como Recurso Final

Em cenários onde subconsultas não resolvem, como operações de grouping sets em tabelas distribuídas, tabelas temporárias podem ser utilizadas.

Exemplo de consulta não suportada:

-- Esta operação falha em tabelas distribuídas
SELECT produto_id, atividade_tipo, publico,
       GROUPING(atividade_tipo, publico),
       MIN(registro_em)
FROM registros_eventos
WHERE produto_id IN (101, 205, 310)
GROUP BY produto_id, ROLLUP(atividade_tipo, publico);

Solução com tabela temporária:

-- Transferir dados relevantes para o coordenador
CREATE TEMP TABLE dados_temporarios AS (
  SELECT produto_id, atividade_tipo, publico, registro_em
  FROM registros_eventos
  WHERE produto_id IN (101, 205, 310)
);

-- Executar agregação localmente
SELECT produto_id, atividade_tipo, publico,
       GROUPING(atividade_tipo, publico),
       MIN(registro_em)
FROM dados_temporarios
GROUP BY produto_id, ROLLUP(atividade_tipo, publico);

Criar tabelas temporárias no coordenador deve ser a última opção, pois está limitada pelos recursos de disco e CPU do nó.

Tags: Citus CTE

Publicado em 6-15 07:29 por Thomas