Estou tendo dificuldade em encontrar explicações 'lay' de como os índices são armazenados em cache no PostgreSQL, então gostaria de uma verificação da realidade em qualquer uma ou todas essas suposições:
- Índices PostgreSQL, como linhas, vivem no disco, mas podem ser armazenados em cache.
- Um índice pode estar inteiramente no cache ou não estar.
- Se é armazenado em cache ou não, depende da frequência com que é usado (conforme definido pelo planejador de consulta).
- Por esta razão, a maioria dos índices 'sensatos' estarão no cache o tempo todo.
- Os índices residem no mesmo cache (o
buffer cache
?) que as linhas e, portanto, o espaço de cache usado por um índice não está disponível para as linhas.
Minha motivação para entender isso decorre de outra pergunta que fiz , onde foi sugerido que índices parciais podem ser usados em tabelas onde a maioria dos dados nunca será acessada.
Antes de fazer isso, gostaria de deixar claro que empregar um índice parcial traz duas vantagens:
- Reduzimos o tamanho do índice no cache, liberando mais espaço para as próprias linhas no cache.
- Reduzimos o tamanho do B-Tree, resultando em uma resposta de consulta mais rápida.
Brincando um pouco com pg_buffercache , pude obter respostas para algumas de suas perguntas.
pg_buffercache
, a resposta é um SIM definitivo . Vale a pena observar que os dados da tabela temporária não são armazenados em cache aqui.EDITAR
Encontrei o excelente artigo de Jeremiah Peschka sobre armazenamento de tabelas e índices. Com informações de lá, eu poderia responder (2) também. Eu configurei um pequeno teste, para que você mesmo possa verificar.
Em suma, isso mostra que índices e tabelas podem ser armazenados em cache página por página, portanto, a resposta para (2) é NÃO .
E uma última para ilustrar tabelas temporárias não armazenadas em cache aqui:
As páginas de índice são buscadas quando uma consulta decide que serão úteis para reduzir a quantidade de dados da tabela necessários para responder a uma consulta. Somente os blocos do índice navegados para realizar isso são lidos. Sim, eles vão para o mesmo pool shared_buffers onde os dados da tabela são armazenados. Ambos também são apoiados pelo cache do sistema operacional como uma segunda camada de cache.
Você pode facilmente ter 0,1% de um índice na memória ou 100% dele. A ideia de que a maioria dos "índices 'sensatos' estarão no cache o tempo todo" cai por terra quando você tem consultas que tocam apenas um subconjunto de uma tabela. Um exemplo comum é se você tiver dados orientados ao tempo. Freqüentemente, eles geralmente navegam no final recente da mesa, raramente visitando a história antiga. Lá você pode encontrar todos os blocos de índice necessários para navegar para e ao redor do final recente na memória, enquanto muito poucos necessários para navegar nos registros anteriores estão lá.
As partes complicadas da implementação não são como os blocos entram no cache do buffer. São as regras sobre quando eles saem. Minha conversa sobre o cache de buffer do PostgreSQL e as consultas de exemplo incluídas podem ajudá-lo a entender o que está acontecendo lá e ver o que realmente está se acumulando em um servidor de produção. Pode ser surpreendente. Há muito mais sobre todos esses tópicos em meu livro PostgreSQL 9.0 High Performance também.
Os índices parciais podem ser úteis porque reduzem o tamanho do índice e, portanto, são mais rápidos de navegar e deixam mais RAM para armazenar em cache outras coisas. Se a sua navegação no índice é tal que as partes que você toca estão sempre na RAM, de qualquer maneira, isso pode não comprar uma melhoria real.