Estou desenvolvendo um aplicativo em Ruby on Rails com o banco de dados PostgreSQL (9.4). Para o meu caso de uso, as colunas nas tabelas serão consultadas com muita frequência, pois todo o ponto do aplicativo está procurando atributos muito específicos em um modelo.
No momento, estou decidindo se deve usar um integer
tipo ou simplesmente usar um tipo de string típico (por exemplo character varying(255)
, qual é o padrão no 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 enum não excede 5, significando que o índice seria mais ou menos fixo durante toda a vida útil do aplicativo ; portanto, os índices inteiro e de seqüência de caracteres seriam idênticos no número de nós.
No entanto, a sequência que seria indexada poderia ter cerca de 20 caracteres, que na memória é aproximadamente 5x do número inteiro (se um número inteiro tiver 4 bytes e as seqüências de caracteres forem ASCII puro a 1 byte por caractere, isso é válido). Não sei como os mecanismos de banco de dados fazem pesquisas de índice, mas se precisar "varrer" a string até corresponder exatamente , isso significa que a pesquisa de string seria 5x mais lenta que uma pesquisa inteira; a "varredura" até a correspondência para a pesquisa inteira seria de 4 bytes em vez de 20. Isso é o que estou imaginando:
O valor da pesquisa é (inteiro) 4:
digitalizando ............................ ENCONTRADO | obtendo registros ... | BYTE_1 | BYTE_2 | BYTE_3 | BYTE_4 | BYTE_5 | BYTE_6 | BYTE_7 | BYTE_8 | ... |
O valor da pesquisa é (string) "some_val" (8 bytes):
digitalizando ................................................. .................................... 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 número inteiro ocupa menos espaço, ele pode ser "correspondido" mais rapidamente do que o equivalente em cadeia. Talvez esse seja um palpite completamente errado, mas eu não sou especialista, por isso estou perguntando a vocês! Suponho que essa 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 no uso de nenhum deles, portanto o próprio índice não mudaria (a menos que eu adicionasse um novo valor à enumeração). Nesse caso, haveria uma diferença de desempenho no uso de integer
ou varchar(255)
, ou o uso de um tipo inteiro faz mais sentido?
A razão pela qual estou perguntando é que o enum
tipo do Rails mapeia números 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 da enumeração é válido, porque um valor inválido causará um ArgumentError
antes que qualquer validação possa ser executada. O uso de um string
tipo permitiria validações, mas se houver um custo de desempenho, eu preferiria me afastar do problema de validação.
fonte
varchar(255)
vs. por exemplovarchar(260)
. Pode ter acontecido isso com o SQL Server 6.x, mas isso não ocorre há muito tempo.