Eu tenho uma lista enorme de matrizes inteiras (300.000.000 registros) armazenadas no banco de dados Postgres 9.2. Desejo pesquisar com eficiência esses registros para uma correspondência exata (somente igualdade). Já ouvi falar do módulo intarray e dos índices gist-gin correspondentes. Gostaria de fazer as seguintes perguntas:
- O PostgreSQL usa uma função hash para verificar a igualdade de arrays inteiros ou executa um algoritmo de força bruta comparando um a um os elementos do array?
- Se o PostgreSQL usa uma função hash, existe algum código de função PostgreSQL para realmente obter o resultado da função hash para uma matriz específica?
- Qual índice será melhor para tal tarefa? B-tree ou os índices gist-gin fornecidos pelo módulo intarray? O dataset será estático, ou seja, uma vez inseridos todos os registros não haverá mais inserções. Portanto, construir o índice/atualizar o tempo do índice não é importante para mim.
P: O PostgreSQL usa uma função hash para verificar a igualdade de arrays inteiros ou executa um algoritmo de força bruta comparando um a um os elementos do array?
Não de acordo com funções e operadores de matriz no documento:
Nenhuma menção de hash.
intarray fornece outros operadores, mas não substitui o operador de igualdade entre
int[]
. A função _int_same() mais próxima que ela expõe é semanticamente diferente (a ordem dos elementos não importa) e é implementada como classificação+comparação sequencial, não hashing.Felizmente, implementar uma pesquisa rápida baseada em hash no nível SQL não é difícil e, no seu caso (arrays grandes, sem atualizações, correspondência exata), pode até ser o método mais eficaz.
Passos:
1) escolha uma função hash. Eu sugeriria
md5
na representação de texto da matriz:A função
digest(text,text)
faz parte dapgcrypto
extensão. Comparado amd5
ele tem a vantagem de produzir binário (16 bytes) em vez de hexadecimal (32 bytes) para um índice mais enxuto.2) crie um índice funcional:
Será várias ordens de magnitude mais rápido do que um índice GIN para o tipo de conjunto de dados que você possui (na verdade, eu me preocuparia com a criação do índice GIN levando um tempo realmente irracional, mas tente).
3) use assim:
1) como você já descobriu, você não pode usar b-tree porque o tamanho do índice é maior que o tamanho da página
2) dado:
Você teria que usar o GIN. E não, o GIN não usa funções de hash nem um algoritmo de força bruta. É um índice reverso: