Eu tenho tentado COUNT(*)
uma tabela com 150.000 linhas que tem uma chave primária. É ferramenta cerca de 5 minutos, então eu descobri que este é um problema de indexação.
Citando o manual do PostgreSQL :
O REINDEX é semelhante a uma remoção e recriação do índice, pois o conteúdo do índice é reconstruído do zero. No entanto, as considerações de bloqueio são bastante diferentes. REINDEX bloqueia gravações, mas não leituras da tabela pai do índice. Também é necessário um bloqueio exclusivo no índice específico que está sendo processado, o que bloqueará as leituras que tentam usar esse índice (...) O subsequente CREATE INDEX bloqueia gravações, mas não leituras; como o índice não está lá, nenhuma leitura tentará usá-lo, o que significa que não haverá bloqueio, mas as leituras podem ser forçadas a verificações seqüenciais caras.
A partir de sua própria experiência, você pode dizer:
- é
REINDEXING
perigoso? Isso pode prejudicar a consistência dos dados? - Pode demorar muito tempo?
- É uma solução provável para o meu cenário?
Atualizar:
A solução que funcionou para nós foi recriar o mesmo índice com um nome diferente e excluir o índice antigo.
A criação do índice é muito rápida e reduzimos o tamanho do índice de 650 MB para 8 MB. Usar um COUNT(*)
com between
leva apenas 3 segundos.
COUNT(*)
é a melhor escolha:If you are using count(*), the database is free to use any column to count, which means it can pick the smallest covering index to scan (note that this is why count(*) is much better than count(some_field), as long as you don't care if null values of some_field are counted). Since indexes often fit entirely in memory, this means count(*) is often very fast.