Uma view contra uma view materializada

Prévia grátis 3 min de leitura

Uma view guarda uma query. Uma view materializada guarda a resposta. Todo o resto sobre elas vem dessa única diferença.

A view comum

CREATE VIEW active_course_counts AS
  SELECT level, COUNT(*) AS total FROM courses WHERE active GROUP BY level;

Isso não guarda dado nenhum. Fazer select nela roda a query por trás, toda vez, contra as tabelas vivas. É uma query com nome: um jeito de parar de repetir SQL, e não um jeito de deixá-lo mais rápido.

O resultado está sempre em dia, porque é calculado na hora.

A view materializada

CREATE MATERIALIZED VIEW active_course_counts AS
  SELECT level, COUNT(*) AS total FROM courses WHERE active GROUP BY level;

Uma palavra, e o sentido se inverte. O Postgres roda a query uma vez e guarda as linhas em disco. Fazer select nela lê essas linhas guardadas, sem agregação e sem varrer a courses.

E o resultado é uma fotografia. Ele reflete as tabelas como estavam na última vez em que ela foi construída, e não se atualiza quando as linhas por trás mudam.

flowchart TB
  V["CREATE VIEW"] --> V1["guarda o texto da query"]
  V1 --> V2["sempre atual. custa a query inteira toda vez"]
  M["CREATE MATERIALIZED VIEW"] --> M1["guarda as linhas resultantes"]
  M1 --> M2["rápida de ler. desatualizada até o refresh"]
  M2 --> M3["o refresh agora é seu"]

O que você ganha

O trabalho caro sai do caminho de leitura. Uma agregação sobre milhões de linhas vira uma varredura de algumas centenas de linhas guardadas.

E ela é uma relação de verdade. Você pode fazer SELECT nela, fazer join com outras tabelas, criar índices e usá-la num WHERE: tudo o que uma tabela faz, sobre dados que eram caros de calcular.

O que você assume

O refresh. Nada atualiza uma view materializada sozinho. Você decide quando ela é reconstruída, e tudo entre uma reconstrução e outra está desatualizado.

Essa é a mesma troca de qualquer cache, e é por isso que as próximas lições comparam as duas coisas o tempo todo. A pergunta interessante não é "uma view materializada ou nada", e sim "uma view materializada ou o cache que você já tem".

Onde esta aplicação está

Ela não tem nenhuma das duas.

views materializadas: 0
views comuns:         0

O que ela tem é um cache no nível da aplicação em volta do tipo de query para o qual uma view materializada existe:

Rails.cache.fetch("admin/stats/#{resolved}", expires_in: 5.minutes) do

O Admin::StatsQuery agrega várias tabelas para montar oito conjuntos de dados de gráfico, e fica em cache por cinco minutos. Isso é uma view materializada implementada em Ruby, e a lição 3 compara as duas direito.

Pontos-chave

  • Uma view guarda uma query e está sempre em dia. Uma view materializada guarda linhas e é uma fotografia.
  • A diferença é uma palavra-chave, e ela inverte para que o objeto serve.
  • Uma view materializada é uma relação de verdade: dá para fazer join com ela, indexá-la e usá-la num WHERE.
  • Nada a atualiza sozinho. Isso é com você, e tudo entre um refresh e outro está desatualizado.
  • Esta aplicação não tem nenhuma view de nenhum dos dois tipos, e em vez disso guarda o Admin::StatsQuery em cache no Ruby.
Aula 1 de 7 · grátis

Continue com a aula 2

O refresh é o problema inteiro

Trata do lock ACCESS EXCLUSIVE do REFRESH, do índice único do CONCURRENTLY e de quando atualizar.

Com uma conta grátis você também tem os quizzes, seu progresso e suas anotações, e a discussão.

Digite para buscar...