Uma view contra uma view materializada
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::StatsQueryem cache no Ruby.
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.