Estou desenvolvendo uma aplicação em Ruby on Rails com o banco de dados PostgreSQL (9.4). Para o meu caso de uso, as colunas nas tabelas serão pesquisadas com muita frequência, pois o objetivo principal do aplicativo é procurar atributos muito específicos em um modelo.
Atualmente estou decidindo se devo usar um integer
tipo ou simplesmente usar um tipo de string típico (por exemplo character varying(255)
, que é o padrão em Rails ) para as colunas, pois não tenho certeza de qual será a diferença de desempenho no índice.
Essas colunas são enumerações . Eles têm um tamanho fixo para a quantidade de valores possíveis que podem ter. A maioria dos comprimentos de enumeração não excede 5, o que significa que o índice seria mais ou menos fixo durante toda a vida útil do aplicativo ; assim, os índices integer e string seriam idênticos no número de nós.
No entanto, a string que seria indexada pode ter cerca de 20 caracteres, o que na memória é aproximadamente 5x o número inteiro (se um inteiro tiver 4 bytes e as strings forem ASCII puro em 1 byte por caractere, isso será válido). Eu não sei como os mecanismos de banco de dados fazem pesquisas de índice, mas se ele precisar "varrer" a string até que ela corresponda exatamente , então, em essência, isso significa que a pesquisa de string seria 5x mais lenta que uma pesquisa de inteiro; o "scan" until match para a pesquisa de inteiros seria de 4 bytes em vez de 20. Isto é o que estou imaginando:
O valor de pesquisa é (inteiro) 4:
digitalização......................... ENCONTRADO | obtendo registros... |BYTE_1|BYTE_2|BYTE_3|BYTE_4|BYTE_5|BYTE_6|BYTE_7|BYTE_8|...|
O valor de pesquisa é (string) "some_val" (8 bytes):
digitalização.................................................. .................................... ENCONTRADO | obtendo registros... |BYTE_1|BYTE_2|BYTE_3|BYTE_4|BYTE_5|BYTE_6|BYTE_7|BYTE_8|...|
Espero que isso faça sentido. Basicamente, como o inteiro ocupa menos espaço, ele pode ser "combinado" mais rapidamente do que sua contraparte de string. Talvez este seja um palpite completamente errado, mas eu não sou especialista, então é por isso que estou perguntando a vocês! Suponho que esta resposta que acabei de encontrar parece apoiar minha hipótese, mas quero ter certeza.
O número de valores possíveis na coluna não mudaria usando nenhum deles, então o índice em si não mudaria (a menos que eu adicionasse um novo valor ao enum). Nesse caso, haveria uma diferença de desempenho em usar integer
ou varchar(255)
, ou usar um tipo inteiro faz mais sentido?
A razão pela qual estou perguntando é que o enum
tipo do Rails mapeia inteiros para chaves de string, mas eles não devem ser colunas voltadas para o usuário. Essencialmente, você não pode verificar se o valor enum é válido, porque um valor inválido causará um erro ArgumentError
antes que qualquer validação possa ser executada. Usar um string
tipo permitiria validações, mas se houver um custo de desempenho, prefiro apenas contornar o problema de validação.