Visão geral das projeções
As projeções armazenam dados em um formato que otimiza a execução de consultas. Esse recurso é útil para:- Executar consultas em uma coluna que não faz parte da chave primária
- Pré-agregar colunas, reduzindo tanto o processamento quanto a E/S
Uso de discoAs projeções criam internamente uma nova tabela oculta, o que significa que será necessário mais E/S e mais espaço em disco.
Por exemplo, se a projeção tiver uma chave primária diferente, todos os dados da tabela original serão duplicados.
Usando projeções
Exemplo de filtragem sem usar chaves primárias
Criando a tabela:ALTER TABLE, podemos adicionar a projeção a uma tabela existente:
user_name rapidamente, mesmo que, na tabela original, user_name não tenha sido definido como PRIMARY_KEY.
No momento da consulta, o ClickHouse determina que menos dados serão processados se a projeção for usada, pois os dados estão ordenados por user_name.
system.query_log. No campo projections, temos o nome da projeção usada, ou ele fica vazio se nenhuma tiver sido usada:
Exemplo de consulta com pré-agregação
Crie a tabela com a projeçãoprojection_visits_by_user:
GROUP BY usando o campo user_agent.
Esta consulta não usará a projeção definida, pois a pré-agregação não é compatível.
GROUP BY:
system.query_log para verificar se uma projeção foi usada.
O campo projections mostra o nome da projeção usada.
Ele ficará vazio se nenhuma projeção tiver sido usada:
Criando e usando índices de projeção
Criando um índice de projeção:_part_offset mantém seu valor mesmo após mesclagens e mutações, o que o torna valioso para indexação secundária. Podemos aproveitar isso em consultas:
Exemplo de projeção com cláusula WHERE
As projeções podem incluir uma cláusulaWHERE para armazenar apenas um subconjunto de linhas. Isso é útil quando as consultas filtram com frequência por um predicado conhecido — a projeção materializa apenas as linhas correspondentes, reduzindo o uso de armazenamento e melhorando o desempenho das consultas.
Criando uma tabela e adicionando uma projeção filtrada:
WHERE de uma consulta implica a cláusula WHERE da projeção (ou seja, toda condição no filtro da projeção também está presente no filtro da consulta), o otimizador pode usar a projeção automaticamente quando determinar que isso é vantajoso:
Manipulação de projeções
As seguintes operações com projeções estão disponíveis:ADD PROJECTION
Use a instrução abaixo para adicionar uma descrição de projeção aos metadados de uma tabela:Quando uma projeção define uma cláusula
WHERE, apenas as linhas que atendem ao predicado são materializadas. O otimizador pode usar essa projeção quando o WHERE da consulta implica logicamente o WHERE da projeção e ela é vantajosa para o plano de consulta. Isso se aplica tanto a projeções normais quanto a projeções agregadas.Cláusula WITH SETTINGS
WITH SETTINGS define configurações da projeção, que personalizam como a projeção armazena os dados (por exemplo, index_granularity ou index_granularity_bytes).
Elas correspondem diretamente às configurações de tabela do MergeTree, mas se aplicam somente a esta projeção.
Exemplo:
MODIFY PROJECTION
Use a instrução abaixo para alterar a cláusulaWITH SETTINGS de uma projeção existente sem recriar seus dados:
INDEX em vez da consulta SELECT:
WITH SETTINGS pode ser diferente da definição existente.
A consulta da projeção em si (ou, no caso de um índice de projeção, a expressão e o tipo do índice) deve permanecer a mesma, pois as partes de projeção existentes armazenam dados gerados a partir dela. Para alterá-la, use DROP PROJECTION seguido de ADD PROJECTION.
O comando altera apenas os metadados da tabela e não reescreve dados: as partes de projeção existentes mantêm as configurações com as quais foram gravadas, enquanto as partes de projeção gravadas por inserts e mesclagens futuras usam as novas configurações.
MATERIALIZE PROJECTION também não aplica as novas configurações às partes existentes: ele cria a projeção apenas nas partes em que ela está ausente ou corrompida e mantém inalteradas as partes de projeção que já existem.
Para recriar as partes existentes com as novas configurações, execute CLEAR PROJECTION seguido de MATERIALIZE PROJECTION ou faça a mesclagem das partes, por exemplo, com OPTIMIZE TABLE ... FINAL.
Exemplo:
DROP PROJECTION
Use a instrução abaixo para remover a descrição de uma projeção dos metadados de uma tabela e excluir os arquivos da projeção do disco. Isso é implementado como uma mutação.MATERIALIZE PROJECTION
Use a instrução abaixo para construir a projeçãoname nas partes em que ela estiver ausente ou corrompida, opcionalmente apenas na partição partition_name.
As partes que já possuem a projeção permanecem inalteradas, mesmo que as configurações da projeção tenham sido alteradas com MODIFY PROJECTION depois de essas partes terem sido gravadas; para reconstruí-las, execute primeiro CLEAR PROJECTION.
Isso é implementado como uma mutação.
CLEAR PROJECTION
Use a instrução abaixo para excluir os arquivos de projeção do disco sem remover a descrição. Isso é implementado por meio de uma mutação.ADD, MODIFY, DROP e CLEAR são leves, no sentido de que apenas alteram metadados ou removem arquivos.
Além disso, esses comandos são replicados e sincronizam os metadados de projeção por meio do ClickHouse Keeper ou do ZooKeeper.
A manipulação de projeções tem suporte apenas em tabelas com o motor
*MergeTree (incluindo variantes replicadas).Controlando o comportamento da mesclagem de projeções
Quando você executa uma consulta, o ClickHouse escolhe entre ler da tabela original ou de uma de suas projeções. A decisão de ler da tabela original ou de uma de suas projeções é tomada individualmente para cada parte da tabela. Em geral, o ClickHouse procura ler o mínimo possível de dados e emprega alguns recursos para identificar a melhor parte a ser lida, por exemplo, amostrando a chave primária de uma parte. Em alguns casos, partes da tabela de origem não têm partes de projeção correspondentes. Isso pode acontecer, por exemplo, porque a criação de uma projeção para uma tabela em SQL é “lazy” por padrão: ela afeta apenas os dados inseridos posteriormente, mas mantém as partes existentes inalteradas. Como uma das projeções já contém os valores agregados pré-computados, o ClickHouse tenta ler das partes de projeção correspondentes para evitar agregar novamente em tempo de execução da consulta. Se uma parte específica não tiver a parte de projeção correspondente, a execução da consulta recorre à parte original. Mas o que acontece se as linhas da tabela original mudarem de forma não trivial devido a mesclagens em segundo plano não triviais de partes de dados? Por exemplo, suponha que a tabela seja armazenada usando o mecanismo de tabelaReplacingMergeTree.
Se a mesma linha for detectada em múltiplas partes de entrada durante a mesclagem, apenas a versão mais recente da linha (da parte inserida mais recentemente) será mantida, enquanto todas as versões mais antigas serão descartadas.
Da mesma forma, se a tabela for armazenada usando o mecanismo de tabela AggregatingMergeTree, a operação de mesclagem pode consolidar linhas iguais nas partes de entrada (com base nos valores da chave primária) em uma única linha para atualizar estados de agregação parciais.
Antes do ClickHouse v24.8, as partes de projeção ou ficavam silenciosamente dessincronizadas em relação aos dados principais, ou determinadas operações, como atualizações e exclusões, simplesmente não podiam ser executadas, já que o banco de dados lançava automaticamente uma exceção se a tabela tivesse projeções.
Desde a v24.8, uma nova configuração no nível da tabela deduplicate_merge_projection_mode controla o comportamento caso as operações de mesclagem em segundo plano não triviais mencionadas acima ocorram em partes da tabela original.
Mutações de exclusão são outro exemplo de operações de mesclagem de partes que removem linhas nas partes da tabela original. Desde a v24.7, também temos uma configuração para controlar o comportamento em relação às mutações de exclusão acionadas por exclusões leves: lightweight_mutation_projection_mode.
Abaixo estão os valores possíveis para deduplicate_merge_projection_mode e lightweight_mutation_projection_mode:
throw(padrão): uma exceção é lançada, impedindo que as partes de projeção fiquem dessincronizadas.drop: As partes afetadas da tabela de projeção são descartadas. As consultas recorrerão à parte da tabela original nos casos em que as partes de projeção forem afetadas.rebuild: A parte de projeção afetada é recriada para permanecer consistente com os dados da parte da tabela original.
Limitações
Não é possível usar uma colunaALIAS na cláusula ORDER BY de uma projeção. Por exemplo:
ALIAS não são armazenadas fisicamente e são calculadas em tempo de consulta, portanto não ficam disponíveis durante o caminho de gravação da parte de projeção, quando a expressão de ordenação é avaliada.
Em vez disso, use colunas MATERIALIZED ou insira a expressão diretamente: