Analytics em tempo realArmazenamento de dadosObservabilidadeAI/MLCloudOss
Pré-requisitos
- A running ClickHouse Cloud service. If you don’t have one yet, complete the Create your first Cloud service quickstart first.
uk_price_paid criada lá.
O que você vai criar
uk_price_paid por town ou county exige uma varredura completa da tabela, porque ela é ordenada por (postcode, addr1, addr2).
Neste guia de início rápido, você vai resolver esse problema criando uma visão materializada que armazena os mesmos dados ordenados por (town, date), permitindo buscas rápidas por cidade sem alterar a tabela original.
Ao final, você entenderá como visões materializadas funcionam como gatilhos de inserção, como fazer backfill dos dados existentes e o trade-off de espaço em disco ao armazenar os dados duas vezes.
1
Entenda por que você precisa de uma visão materializada
Sua tabelauk_price_paid está ordenada por (postcode, addr1, addr2). Isso significa que o ClickHouse pode ignorar grandes blocos de dados quando você filtra por postcode, addr1 ou addr2, mas consultas que filtram por town precisam examinar cada uma das linhas — todas as 30 milhões.Você poderia criar uma segunda tabela com um ORDER BY diferente, mas aí precisaria se lembrar de inserir os dados nas duas tabelas sempre que novos dados chegassem. Uma visão materializada automatiza isso: ela monitora as inserções em uma tabela de origem, transforma as linhas e as grava automaticamente em uma tabela de destino.Pense em uma visão materializada como um gatilho de inserção — toda vez que linhas são inseridas na tabela de origem, a consulta SELECT da MV é executada sobre o novo bloco de linhas, e o resultado é inserido na tabela de destino.2
Crie a tabela de destino
Uma visão materializada precisa de algum lugar para armazenar seu resultado. É apenas uma tabela MergeTree comum — você tem controle total sobre seu esquema,ORDER BY e PARTITION BY.Crie uma tabela ordenada por (town, date) com apenas as colunas necessárias para consultas por cidade:3
Crie a visão materializada
Agora, crie a visão materializada que conecta a tabela de origem (uk_price_paid) à tabela de destino (uk_price_paid_by_town):TO uk_price_paid_by_town informa ao ClickHouse que ele deve gravar a saída do SELECT na sua tabela de destino. A partir de agora, sempre que linhas forem inseridas em uk_price_paid, essa MV será acionada e inserirá as linhas transformadas em uk_price_paid_by_town.Há uma ressalva importante: visões materializadas só são acionadas por inserções. Se você excluir ou atualizar linhas na tabela de origem, a tabela de destino não saberá disso — as MVs não permanecem sincronizadas com exclusões ou atualizações. Se você precisar desse tipo de sincronização, considere usar projeções.4
Fazer backfill dos dados existentes
A visão materializada processa apenas inserções futuras. As 30 milhões de linhas já emuk_price_paid foram inseridas antes de a MV existir, então a tabela de destino está vazia no momento.Faça o backfill manualmente:5
Consulte a tabela de destino da visão materializada
Agora, execute uma consulta com filtro emtown na tabela de destino e compare o resultado com uma consulta feita diretamente na tabela de origem.Primeiro, consulte a tabela de origem:town não está no ORDER BY da tabela de origem.Agora execute a mesma consulta na tabela de destino da visão materializada:(town, date) e o ClickHouse pode ignorar todos os dados que não correspondem a LONDON.Execute SHOW TABLES para ver o que foi criado:uk_price_paid_by_town (a tabela de destino) quanto uk_price_paid_by_town_mv (a view). Como você usou CREATE MATERIALIZED VIEW ... TO, tem controle sobre o nome da tabela de destino. Se omitir a cláusula TO, o ClickHouse criará uma tabela de destino com nome implícito (.inner.xxx), com a qual é mais difícil trabalhar diretamente.
Por isso, recomenda-se criar visões materializadas usando a cláusula TO.6
Observe que os dados são armazenados duas vezes
Visões materializadas oferecem leituras mais rápidas, em troca de espaço adicional em disco. Consultesystem.parts para ver quanto espaço cada tabela usa:uk_price_paid, ordenados por (postcode, addr1, addr2), e outra em uk_price_paid_by_town, ordenados por (town, date). Esse é o trade-off fundamental: você usa mais espaço em disco em troca de leituras mais rápidas para diferentes padrões de acesso.A tabela de destino pode ocupar menos espaço em disco porque contém menos colunas, e a ordenação (town, date) pode ser compactada de forma diferente da original.