Todos os produtos
Search
Central de documentação

PolarDB:Aceleração de busca por texto completo (rum)

Última atualização: Jun 28, 2026

A extensão rum oferece um método de acesso a índice alternativo ao GIN. Ela armazena dados posicionais e adicionais diretamente no índice, permitindo ordenação mais rápida em buscas por texto completo, correspondência de frases e ordenação por colunas anexadas.

Pré-requisitos

  • é compatível com as seguintes versões:

    • (versão secundária do mecanismo 2.0.18.1.2.0 ou posterior)

    • (versão secundária do mecanismo 2.0.17.6.4.0 ou posterior)

    • (versão secundária do mecanismo 2.0.16.8.3.0 ou posterior)

    • (versão secundária do mecanismo 2.0.15.7.1.1 ou posterior)

    • (versão secundária do mecanismo 2.0.14.5.3.0 ou posterior)

    Nota

    Visualize a versão secundária do mecanismo no console ou execute a instrução SHOW polardb_version;. Caso sua versão não atenda aos requisitos, atualize a versão secundária do mecanismo. Para obter mais informações, consulte Visualizar a versão secundária do mecanismo.

  • Compatibilidade de extensões: O operador % da extensão RUM entra em conflito com o operador % da extensão smlar. Devido a esse conflito, não é possível criar e usar ambas as extensões no mesmo schema de banco de dados. Antes de instalar a extensão RUM, confirme que a extensão smlar não está em uso no seu ambiente ou instale as duas extensões em schemas diferentes.

Pré-requisitos

  • Versões suportadas do : , com versão secundária do mecanismo 2.0.14.5.3.0 ou posterior.

    Nota

    Visualize a versão secundária do mecanismo no console ou execute a instrução SHOW polardb_version;. Caso sua versão não atenda aos requisitos, atualize a versão secundária do mecanismo. Para obter mais informações, consulte Visualizar a versão secundária do mecanismo.

  • Compatibilidade de extensões: O operador % da extensão RUM entra em conflito com o operador % da extensão smlar. Devido a esse conflito, não é possível criar e usar ambas as extensões no mesmo schema de banco de dados. Antes de instalar a extensão RUM, confirme que a extensão smlar não está em uso no seu ambiente ou instale as duas extensões em schemas diferentes.

Visão geral

A tabela a seguir compara o índice rum com o índice GIN integrado. Use esta comparação para decidir qual tipo de índice melhor se adapta à sua carga de trabalho.

Dimensão de Comparação

Índice GIN (Integrado)

Índice RUM

Recomendação

Vantagem Principal

Bom desempenho de escrita. Tamanho de índice relativamente pequeno.

Alto desempenho de ordenação. Suporta buscas por frases e ordenação por colunas anexadas.

A extensão RUM é a escolha preferencial para cenários que exigem ordenação dos resultados de busca.

Desempenho de Ordenação

Lento. Exige consultas à tabela para obter dados de ordenação. O desempenho cai drasticamente conforme o volume de dados aumenta.

Rápido. Realiza a ordenação diretamente no índice. Não requer consultas à tabela.

Utilize a extensão RUM se você ordena frequentemente os resultados de busca por texto completo, como por relevância, tempo ou preço.

Busca por Frases

Lenta. Requer consultas à tabela para obter informações sobre a posição das palavras e verificar as frases.

Rápida. As informações de posição das palavras já estão armazenadas no índice. Consultas à tabela são desnecessárias.

Recomendada para cenários que demandam buscas por frases de alto desempenho.

Ordenação por Colunas Anexadas

Não suportada. Não é possível armazenar informações de colunas extras, como timestamps, no índice.

Suportada. Permite anexar outras colunas ao índice para realizar ordenações personalizadas de alto desempenho.

A extensão RUM apresenta vantagem significativa em cenários que exigem ordenação por campos como hora de publicação ou atualização de artigos.

Desempenho de Escrita

Relativamente rápido.

Relativamente lento, pois mantém um schema de índice mais complexo.

Em tabelas com muitas operações de INSERT ou UPDATE, avalie cuidadosamente a sobrecarga de escrita introduzida pela extensão RUM.

Tamanho do Índice

Relativamente pequeno.

Relativamente grande, pois exige espaço extra para armazenar posições e informações adicionais.

Avalie seus custos de armazenamento. Se o tamanho do índice for um gargalo importante, considere usar um índice RUM hash ou continuar utilizando o índice GIN.

Busca por Prefixo

Suportada.

Suportada por rum_tsvector_ops. Não suportada pela série hash.

Evite índices RUM hash caso a busca por prefixo seja um requisito essencial.

O índice rum troca espaço por tempo: ele aumenta o tamanho do índice e a sobrecarga de escrita em troca de uma ordenação, busca por frases e ordenação por colunas anexadas significativamente mais rápidas. Escolha o rum quando sua carga de trabalho envolver busca por texto completo com requisitos complexos de ordenação. Para cargas de trabalho intensivas em escrita ou correspondência simples de texto, o índice GIN integrado é mais econômico.

Instale a extensão

Instale a extensão

Conecte-se ao seu banco de dados e execute a seguinte instrução:

CREATE EXTENSION rum;

Desinstalar a extensão

Para desinstalar a extensão:

DROP EXTENSION rum;

Operadores e classes de operadores

A extensão RUM fornece várias classes de operadores para suportar diferentes tipos de dados e cenários de consulta. Escolha a classe de operadores apropriada para criar um índice com base nas suas necessidades específicas.

Nota

Uma classe de operadores define como um índice RUM processa um tipo de dados específico. Cada classe inclui operadores suportados para cláusulas WHERE e ORDER BY, permitindo que o PostgreSQL utilize o índice RUM para acelerar consultas.

Portanto, escolher a classe de operadores correta é fundamental para garantir a eficácia do índice RUM. Para obter mais informações, consulte Operator Classes and Operator Families.

Operadores

Operador

Tipos Suportados

Tipo de Valor de Retorno

Descrição

A @@ B

Esquerda: tsvector, Direita: tsquery

bool

Retorna se o vetor de texto completo corresponde à condição de consulta. Realiza um cálculo de distância.

A <=> B

Esquerda: tsvector, Direita: tsquery

float4

Retorna o valor da distância entre o vetor de texto completo e a condição de consulta. Um valor menor indica maior relevância.

timestamp, timestamptz, int2, int4, int8, float4, float8, money, oid

float8

Retorna a diferença absoluta entre dois valores.

  • A diferença de tempo é em segundos, com precisão de seis casas decimais (microssegundos).

  • A diferença monetária é em centavos, com precisão até o centavo.

A <=| B

timestamp, timestamptz, int2, int4, int8, float4, float8, money, oid

float8

Retorna B - A apenas se A ≤ B. Caso contrário, retorna infinito.

A |=> B

timestamp, timestamptz, int2, int4, int8, float4, float8, money, oid

float8

Retorna A - B apenas se A > B. Caso contrário, retorna infinito.

Classe de Operadores

Classe de Operadores

Tipos de Dados Aplicáveis

Principais Operadores Suportados

Função Principal e Descrição

rum_tsvector_ops

tsvector

  • WHERE: A @@ B

  • ORDER BY: A <=> B

Armazena os lexemas e suas informações de posição de um tsvector. Suporta busca por texto completo, busca por prefixo e ordenação por relevância. Esta é a classe de operadores mais utilizada para busca textual.

rum_tsvector_hash_ops

tsvector

  • WHERE: A @@ B

  • ORDER BY: A <=> B

Armazena os valores de hash e as informações de posição dos lexemas do tsvector.

  • Suporta busca por texto completo e ordenação por relevância, mas não suporta busca por prefixo.

  • O tamanho do índice pode ser menor do que com rum_tsvector_ops.

  • Colisões de hash podem ocorrer durante uma busca, exigindo uma nova verificação.

rum_<TYPE>_ops

int2, int4, int8, float4, float8, money, oid, time, timetz, date, interval, macaddr, inet, cidr, text, varchar, char, bytea, bit, varbit, numeric, timestamp, timestamptz

  • WHERE: Para tipos de dados aplicáveis, suporta <, <=, =, >= e > entre valores do mesmo tipo.

  • ORDER BY: Para int2, int4, int8, float4, float8, money, oid, timestamp e timestamptz, suporta as operações <=>, <=| e |=> entre valores do mesmo tipo.

Realiza consultas de intervalo e ordenação por distância em tipos de dados que não sejam texto ou array.

rum_tsvector_addon_ops

tsvector

WHERE: A @@ B

Anexa dados de uma coluna adicional (como um timestamp) a um índice tsvector. Isso permite a busca por texto completo na coluna principal e, simultaneamente, uma ordenação eficiente na coluna anexada.

Nota

O tipo de dados da coluna anexada deve ser suportado por uma classe de operadores rum_<TYPE>_ops correspondente. Para utilizar o índice na aceleração, a ordenação deve usar o operador <=>, <=| ou |=>.

rum_tsvector_hash_addon_ops

tsvector

WHERE: A @@ B

Mesma função que rum_tsvector_addon_ops.

  • Como armazena valores de hash dos lexemas, não suporta busca por prefixo.

  • O tamanho do índice pode ser menor do que com rum_tsvector_addon_ops.

  • Podem ocorrer colisões de hash, exigindo uma nova verificação.

  • A busca pode ser mais lenta do que com rum_tsvector_addon_ops.

rum_tsquery_ops

tsquery

WHERE: A @@ B

Utilizado para indexar uma coluna tsquery. Permite acelerar consultas de forma inversa, encontrando rapidamente quais condições de consulta armazenadas (tsquery) correspondem a um determinado documento (tsvector).

rum_anyarray_ops

anyarray, por exemplo, int[], text[], varchar[]

  • WHERE:

    • &&: Os arrays se sobrepõem (possuem elementos comuns)?

    • @>: O array da esquerda contém todos os elementos do array da direita?

    • <@: Contido em.

    • =: Os arrays são iguais?

    • : Os arrays são semelhantes? (A similaridade é calculada. Se exceder um limiar, os arrays são considerados semelhantes.)

  • ORDER BY

    • <=>: A distância entre dois arrays.

Indexa tipos de array. Suporta operações de array como contenção e sobreposição, além de permitir ordenação pela distância entre arrays.

rum_anyarray_addon_ops

anyarray, por exemplo, int[], text[], varchar[]

  • WHERE:

    • &&: Os arrays se sobrepõem (possuem elementos comuns)?

    • @>: O array da esquerda contém todos os elementos do array da direita?

    • <@: Contido em.

    • =: Os arrays são iguais?

    • : Os arrays são semelhantes? (A similaridade é calculada. Se exceder um limiar, os arrays são considerados semelhantes.)

  • ORDER BY

    • <=>: A distância entre dois arrays.

Anexa dados de uma coluna adicional a um índice de array para suportar cenários de consulta mais complexos.

Nota

O tipo de dados da coluna anexada deve ser suportado por uma classe de operadores rum_<TYPE>_ops correspondente. Para utilizar o índice na aceleração, a ordenação deve usar o operador <=>, <=| ou |=>.

Observações de uso

  • Desempenho de escrita e tamanho do índice: Para acelerar consultas, um índice RUM armazena informações extras, como posições de palavras. Isso torna o índice maior que um índice GIN e aumenta a sobrecarga de criação durante operações de escrita e atualização de dados. Portanto, avalie cuidadosamente o custo da extensão RUM em cenários intensivos em escrita onde o espaço de armazenamento é uma preocupação.

  • Cenários sem suporte a busca por prefixo: Índices criados com as classes de operadores rum_tsvector_hash_ops ou rum_tsvector_hash_addon_ops não suportam busca por prefixo. O motivo é que eles armazenam os valores de hash dos lexemas, e não o texto original.

Exemplo: Ordenar resultados de busca textual por relevância

Quando for necessário ordenar resultados de busca por texto completo por relevância, utilize um índice RUM para evitar a sobrecarga extra de ordenação exigida pelos índices GIN e alcançar um desempenho superior.

  1. Prepare os dados: Primeiro, crie uma tabela de teste.

    CREATE TABLE t1(
      t text,
      t_vec tsvector GENERATED ALWAYS AS (to_tsvector('pg_catalog.english', t)) STORED
    );
    
    -- Insert test data
    INSERT INTO t1(t) VALUES ('The situation is most beautiful');
    INSERT INTO t1(t) VALUES ('It is a beautiful');
    INSERT INTO t1(t) VALUES ('It looks like a beautiful place');
  2. Crie um índice RUM: Utilize a classe de operadores rum_tsvector_ops para criar um índice RUM na coluna tsvector.

    CREATE INDEX t1_t_vec_idx ON t1 USING rum (t_vec rum_tsvector_ops);
  3. Execute uma consulta com ordenação por relevância: Use o operador <=> para consultar e ordenar. Este operador calcula a distância entre a consulta e o texto. Uma distância menor indica maior relevância. Assim, o uso de ORDER BY ordena os resultados por relevância.

    SET enable_seqscan TO off;
    
    SELECT t, t_vec <=> to_tsquery('english', 'beautiful | place') AS rank
    FROM t1
    WHERE t_vec @@ to_tsquery('english', 'beautiful | place')
    ORDER BY t_vec <=> to_tsquery('english', 'beautiful | place');

    O resultado retornado é:

                    t                |  rank   
    ---------------------------------+---------
     It looks like a beautiful place | 8.22467
     The situation is most beautiful | 16.4493
     It is a beautiful               | 16.4493

Exemplo: Ordenar por timestamp com filtragem de texto completo

Em cenários como análise de logs ou busca em e-commerce, é comum precisar realizar uma busca por texto completo e ordenar os resultados por um campo adicional, como timestamp ou preço. O recurso add-on do RUM permite armazenar informações de uma coluna anexada no índice. Isso viabiliza consultas combinadas e ordenações eficientes.

  1. Prepare os dados: Crie uma tabela contendo uma coluna tsvector e uma coluna de timestamp e, em seguida, insira dados de amostra.

    CREATE TABLE tsts (id int, t tsvector, d timestamp);
    INSERT INTO tsts VALUES
    (354, to_tsvector('wr qh'), '2016-05-16 14:21:22.326724'),
    (355, to_tsvector('wr qh'), '2016-05-16 13:21:22.326724'),
    (356, to_tsvector('ts op'), '2016-05-16 18:21:22.326724'),
    (358, to_tsvector('ts op'), '2016-05-16 23:21:22.326724'),
    (371, to_tsvector('wr qh'), '2016-05-17 06:21:22.326724'),
    (406, to_tsvector('wr qh'), '2016-05-18 17:21:22.326724'),
    (415, to_tsvector('wr qh'), '2016-05-19 02:21:22.326724');
  2. Crie um índice RUM com coluna anexada: Utilize a classe de operadores rum_tsvector_addon_ops e especifique a coluna anexada e a coluna de índice principal na cláusula WITH.

    CREATE INDEX tsts_idx ON tsts USING rum (t rum_tsvector_addon_ops, d) WITH (attach = 'd', to = 't');
    Nota

    A sintaxe chave WITH (attach = 'd', to = 't') anexa os valores da coluna d (a coluna anexada, que é um timestamp) às entradas de índice da coluna t (a coluna de índice principal do tipo tsvector). Isso permite que o banco de dados use o índice na coluna t para busca textual e as informações da coluna anexada d para uma ordenação eficiente em uma única varredura de índice. Esse processo evita consultas à tabela e melhora significativamente o desempenho.

  3. Execute uma consulta com ordenação combinada: Consulte registros que contenham palavras específicas e ordene-os pela proximidade do timestamp em relação a um horário alvo.

    SET enable_seqscan TO off;
    
    EXPLAIN (costs off)
    SELECT id, d, d <=> '2016-05-16 14:21:25' AS distance
    FROM tsts
    WHERE t @@ 'wr&qh'
    ORDER BY d <=> '2016-05-16 14:21:25'
    LIMIT 5;

    O plano de execução a seguir mostra que tanto a ordenação quanto a filtragem são concluídas em uma única varredura de índice.

                                      QUERY PLAN                                  
    ------------------------------------------------------------------------------
     Limit
       ->  Index Scan using tsts_idx on tsts
             Index Cond: (t @@ '''wr'' & ''qh'''::tsquery)
             Order By: (d <=> '2016-05-16 14:21:25'::timestamp without time zone)

    O resultado retornado é:

     id  |             d              |   distance    
    -----+----------------------------+---------------
     354 | 2016-05-16 14:21:22.326724 |      2.673276
     355 | 2016-05-16 13:21:22.326724 |   3602.673276
     371 | 2016-05-17 06:21:22.326724 |  57597.326724
     406 | 2016-05-18 17:21:22.326724 | 183597.326724
     415 | 2016-05-19 02:21:22.326724 | 215997.326724

Exemplo: Consultar e ordenar arrays por similaridade

Para cenários como sistemas de tags ou personas de usuários, é necessário consultar eficientemente arrays que contenham elementos específicos e ordená-los pelo grau de sobreposição ou similaridade.

  1. Prepare os dados:

    CREATE TABLE test_array (id serial, i int2[]);
    INSERT INTO test_array(i) VALUES ('{}'), ('{0}'), ('{1,2,3,4}'), ('{1,2,3}'), ('{1,2}'), ('{1}');
  2. Crie um índice RUM para array: Utilize a classe de operadores rum_anyarray_ops para criar um índice na coluna de array.

    CREATE INDEX idx_array ON test_array USING rum (i rum_anyarray_ops);
  3. Execute uma consulta e ordenação de array: Consulte registros que contenham o elemento 1 e ordene-os pela similaridade em relação a {1}.

    SELECT *
    FROM test_array
    WHERE i && '{1}' -- The '&&' operator indicates array overlap.
    ORDER BY i <=> '{1}' ASC; -- The '<=>' operator calculates the distance between arrays. A smaller value indicates greater similarity.

    O resultado retornado é:

         i
    -----------
     {1}
     {1,2}
     {1,2,3}
     {1,2,3,4}

Exemplo: Corresponder documentos a regras de consulta armazenadas

Ao construir sistemas para assinaturas de usuários ou correspondência de regras de alerta, é preciso corresponder rapidamente novos dados, como um artigo, a diversas regras de consulta existentes, como palavras-chave assinadas por usuários. A extensão RUM suporta a criação de um índice no tipo tsquery para realizar correspondências invertidas eficientes.

  1. Prepare os dados das regras de consulta:

    CREATE TABLE query (id serial, q tsquery, tag text);
    INSERT INTO query (q, tag) VALUES
    ('supernova & star', 'sn'),
    ('black', 'color'),
    ('big & bang & black & hole', 'bang'),
    ('spiral & galaxy', 'shape'),
    ('black & hole', 'color');
  2. Crie um índice RUM para tsquery:

    CREATE INDEX query_idx ON query USING rum(q rum_tsquery_ops);
  3. Execute uma consulta de correspondência invertida: Utilize o tsvector de um novo artigo para corresponder a todas as regras tsquery qualificadas.

    SELECT *
    FROM query
    WHERE to_tsvector('black holes never exists before we think about them') @@ q;

    O resultado retornado é:

    id   |    q     |  tag
    -----+----------+-------
    2    | 'black'  | color

Referências