Tenho uma implantação do PostgreSQL 15 que contém uma tabela particionada na ordem de dezenas de milhões de registros.
Tenho brincado com a criação de índices e estou surpreso com o pouco espaço que um índice btree está usando.
Então, a tabela de partição dummy_name_partition_01
tem cerca de 13 milhões de registros. Não tenho certeza se é relevante, mas os registros podem ficar um pouco grandes, com média de 2,66 KiB por registro (a partição tem ~30 GiB sem contar índices).
Uma das colunas (chamada record_type
), que é a coluna com a qual estou brincando com índices, armazena uma string pequena (< 50 caracteres). Embora seja um tipo TEXT e não um ENUM, seu valor sempre será um de cerca de ~300 strings possíveis.
Inicialmente, criei um índice BRIN para essa record_type
coluna para economizar no uso do disco. Parece que o tamanho do índice é de apenas 1 MiB no disco. De fato, minúsculo.
Agora, estou tendo problemas com o postgres realmente usando esse índice BRIN. Ele insiste em fazer varreduras sequenciais, então é como se o índice brin fosse inútil. Eu estava com medo de que um índice btree fosse muito grande, mas então eu descartei o índice BRIN e o criei como BTREE, e seu tamanho é de apenas 92 MiB. Eu esperava algo na faixa de pelo menos 1 GiB!
Para medir o tamanho do índice, estou consultando a information_schema.tables
tabela e usando as funções pg_table_size
, pg_indexes_size
. Ou seja, consultei o tamanho do índice com pg_indexes_size
quando não havia índice, então executei depois de criar o índice e apenas peguei a diferença como sendo o tamanho do índice. Claro que fiz isso algumas vezes para poder obter os números de BRIN vs BTREE.
O índice é tão simples quanto a CREATE INDEX foo_bar ON dummy_namy_partition_01 (record_type)
para btree, e o mesmo, mas a USING BRIN
para o índice brin.
Agora, eu me pergunto: o Postgres de alguma forma armazena um ponteiro para os dados na record_type
coluna em vez de armazenar strings duplicadas por toda parte e então essa seria a razão para o índice estar em quase cem MiBs em vez de alguns gigabytes? Ou, o que está acontecendo aqui?