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)
NotaVisualize 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ãosmlar. 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ãosmlarnã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.
NotaVisualize 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ãosmlar. 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ãosmlarnã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 |
|
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 |
|
Busca por Prefixo |
Suportada. |
Suportada por |
Evite índices RUM |
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.
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 |
Esquerda: |
|
Retorna se o vetor de texto completo corresponde à condição de consulta. Realiza um cálculo de distância. |
|
A |
Esquerda: |
|
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. |
|
|
|
Retorna a diferença absoluta entre dois valores.
|
|
|
A |
|
|
Retorna |
|
A |
|
|
Retorna |
Classe de Operadores
|
Classe de Operadores |
Tipos de Dados Aplicáveis |
Principais Operadores Suportados |
Função Principal e Descrição |
|
|
|
|
Armazena os lexemas e suas informações de posição de um |
|
|
|
|
Armazena os valores de hash e as informações de posição dos lexemas do
|
|
|
|
|
Realiza consultas de intervalo e ordenação por distância em tipos de dados que não sejam texto ou array. |
|
|
|
|
Anexa dados de uma coluna adicional (como um Nota
O tipo de dados da coluna anexada deve ser suportado por uma classe de operadores |
|
|
|
|
Mesma função que
|
|
|
|
|
Utilizado para indexar uma coluna |
|
|
|
|
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. |
|
|
|
|
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 |
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_opsourum_tsvector_hash_addon_opsnã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.
-
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'); -
Crie um índice RUM: Utilize a classe de operadores
rum_tsvector_opspara criar um índice RUM na colunatsvector.CREATE INDEX t1_t_vec_idx ON t1 USING rum (t_vec rum_tsvector_ops); -
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 deORDER BYordena 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.
-
Prepare os dados: Crie uma tabela contendo uma coluna
tsvectore 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'); -
Crie um índice RUM com coluna anexada: Utilize a classe de operadores
rum_tsvector_addon_opse especifique a coluna anexada e a coluna de índice principal na cláusulaWITH.CREATE INDEX tsts_idx ON tsts USING rum (t rum_tsvector_addon_ops, d) WITH (attach = 'd', to = 't');NotaA sintaxe chave
WITH (attach = 'd', to = 't')anexa os valores da colunad(a coluna anexada, que é um timestamp) às entradas de índice da colunat(a coluna de índice principal do tipotsvector). Isso permite que o banco de dados use o índice na colunatpara busca textual e as informações da coluna anexadadpara uma ordenação eficiente em uma única varredura de índice. Esse processo evita consultas à tabela e melhora significativamente o desempenho. -
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.
-
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}'); -
Crie um índice RUM para array: Utilize a classe de operadores
rum_anyarray_opspara criar um índice na coluna de array.CREATE INDEX idx_array ON test_array USING rum (i rum_anyarray_ops); -
Execute uma consulta e ordenação de array: Consulte registros que contenham o elemento
1e 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.
-
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'); -
Crie um índice RUM para tsquery:
CREATE INDEX query_idx ON query USING rum(q rum_tsquery_ops); -
Execute uma consulta de correspondência invertida: Utilize o
tsvectorde um novo artigo para corresponder a todas as regrastsqueryqualificadas.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
rum no GitHub: Documentação oficial e código-fonte.