O PASE não recebe mais manutenção. Use a extensão pgvector. Para mais detalhes, consulte Use the pgvector extension to perform high-dimensional vector similarity searches.
O PASE (extensão de busca ANN do PostgreSQL) adiciona busca vetorial por vizinhos mais próximos aproximados (ANN) ao ApsaraDB RDS for PostgreSQL com dois algoritmos de índice: IVFFlat e Hierarchical Navigable Small World (HNSW).
O PASE realiza buscas de similaridade em vetores existentes. Ele não extrai nem gera vetores de características — você deve fornecê-los.
Pré-requisitos
Antes de começar, verifique se você tem:
Uma instância do ApsaraDB RDS for PostgreSQL com PostgreSQL 11 ou superior (o PostgreSQL 17 não é suportado)
Uma conta privilegiada para executar as instruções SQL deste tópico
Escolha um algoritmo de índice
Ambos os algoritmos equilibram tempo de construção e uso de memória em troca da precisão da consulta (recall). Use esta tabela para decidir:
|
IVFFlat |
HNSW |
|
|
Funcionamento |
Divide os vetores em clusters; consulta um subconjunto de clusters próximos ao alvo |
Constrói um grafo de proximidade multicamadas; percorre das camadas mais grossas até as mais finas |
|
Mais indicado para |
Consultas de alta precisão em que latência de até 100 ms é aceitável |
Grandes conjuntos de dados (dezenas de milhões de vetores) que exigem respostas em menos de 10 ms |
|
Recall de 100% possível? |
Sim, quando o vetor de consulta está no conjunto de dados candidato |
A precisão atinge um platô após certo nível e não aumenta apenas com o ajuste de parâmetros |
|
Tempo de construção |
Rápido |
Lento |
|
Armazenamento |
Baixo |
Maior (armazena vizinhos do grafo de proximidade) |
|
Dados necessários antes da indexação? |
Sim, ao usar clustering interno ( |
Não |
Use o IVFFlat para comparação de imagens e outras cargas de trabalho de alta precisão em que alguma latência de consulta é aceitável.
Use o HNSW para sistemas de recomendação e busca semântica em escala, nos quais a baixa latência é mais importante que o recall perfeito.
Como funciona
IVFFlat
O IVFFlat é uma versão simplificada do algoritmo IVFADC.

O IVFFlat usa k-means para dividir os vetores em clusters. Cada cluster tem um centroide.
Ele localiza os
ncentroides mais próximos do vetor de consulta.Pesquisa todos os vetores nesses
nclusters e retorna oskresultados mais próximos.
Ignorar clusters distantes acelera a consulta, mas pode reduzir o recall — vetores similares à consulta podem ficar fora dos clusters selecionados. Um valor maior para n melhora o recall, porém aumenta o custo computacional.
O IVFFlat difere do IVFADC na segunda fase. O IVFADC usa quantização de produto para evitar a varredura por força bruta, sendo mais rápido, porém menos preciso. O IVFFlat faz busca por força bruta dentro dos clusters selecionados, oferecendo controle direto sobre o equilíbrio entre precisão e velocidade.
HNSW
O HNSW é um algoritmo ANN baseado em grafos.

O HNSW constrói uma estrutura hierárquica de camadas (grafos). Cada camada representa uma visão mais grosseira da camada abaixo.
A busca começa em um elemento aleatório na camada superior.
O HNSW encontra os vizinhos do elemento atual, adiciona-os a uma lista de candidatos de tamanho fixo ordenada por distância e continua a expandir os vizinhos. Quando a lista se estabiliza, o elemento principal torna-se o ponto de entrada para a próxima camada inferior.
Esse processo se repete até percorrer a camada inferior.
O HNSW usa o algoritmo Navigable Small World (NSW) — originalmente projetado para grafos de camada única — para construir cada camada, permitindo travessia mais rápida que os métodos baseados em clustering.
Este tópico pressupõe conhecimento prévio sobre aprendizado de máquina e algoritmos de busca ANN.
Configure o PASE
Etapa 1: Ative a extensão
CREATE EXTENSION pase;
Etapa 2: Calcule a similaridade vetorial (teste rápido opcional)
Use o operador <?> para calcular a similaridade entre dois vetores antes de criar um índice.
Construção do tipo PASE:
SELECT ARRAY[2, 1, 1]::float4[] <?> pase(ARRAY[3, 1, 1]::float4[]) AS distance;
SELECT ARRAY[2, 1, 1]::float4[] <?> pase(ARRAY[3, 1, 1]::float4[], 0) AS distance;
SELECT ARRAY[2, 1, 1]::float4[] <?> pase(ARRAY[3, 1, 1]::float4[], 0, 1) AS distance;
Construção baseada em string:
SELECT ARRAY[2, 1, 1]::float4[] <?> '3,1,1'::pase AS distance;
SELECT ARRAY[2, 1, 1]::float4[] <?> '3,1,1:0'::pase AS distance;
SELECT ARRAY[2, 1, 1]::float4[] <?> '3,1,1:0:1'::pase AS distance;
O operador <?> recebe um float4[] à esquerda e um valor PASE à direita. Ambos os vetores devem ter o mesmo número de dimensões; caso contrário, o PASE retornará um erro de cálculo de similaridade.
No construtor do PASE (float4[], second_param, similarity_method):
Segundo parâmetro: reservado; defina como
0Método de similaridade:
0= distância euclidiana,1= produto escalar (também chamado de produto interno)
Ao usar o método de produto escalar ou similaridade de cosseno, normalize primeiro os vetores de entrada. Um vetor normalizado satisfaz a condiçãode modo que
. Para um vetor normalizado, o produto escalar equivale ao valor do cosseno. O ApsaraDB RDS for PostgreSQL suporta o método de distância euclidiana diretamente; use o método de produto escalar somente após normalizar os vetores.
Etapa 3: Crie um índice
Índice IVFFlat
CREATE INDEX ivfflat_idx ON table_name
USING
pase_ivfflat(column_name)
WITH
(clustering_type = 1, distance_type = 0, dimension = 256, base64_encoded = 0, clustering_params = "10,100");
Parâmetros:
|
Parâmetro |
Obrigatório |
Padrão |
Descrição |
|
|
Sim |
— |
Método de clustering. |
|
|
Não |
|
Método de similaridade. |
|
|
Sim |
— |
Número de dimensões do vetor. Máximo: |
|
|
Não |
|
Codificação do vetor. |
|
|
Sim |
— |
Para clustering interno ( |
Índice HNSW
CREATE INDEX hnsw_idx ON table_name
USING
pase_hnsw(column_name)
WITH
(dim = 256, base_nb_num = 16, ef_build = 40, ef_search = 200, base64_encoded = 0);
Parâmetros:
|
Parâmetro |
Obrigatório |
Valores válidos |
Descrição |
|
|
Sim |
|
Número de dimensões do vetor. |
|
|
Sim |
Recomendado: |
Número de vizinhos armazenados por elemento. Valores maiores melhoram o recall, mas aumentam o tempo de construção e o armazenamento. |
|
|
Sim |
Recomendado: |
Tamanho do heap de candidatos durante a construção do índice. Valores maiores melhoram o recall, mas tornam a construção mais lenta. |
|
|
Sim |
|
Tamanho do heap de candidatos durante as consultas. Valores maiores melhoram o recall, mas reduzem o throughput da consulta. |
|
|
Não |
|
Codificação do vetor. |
Etapa 4: Consulte vetores
Consulta IVFFlat
Use o operador <#> e inclua ORDER BY — o índice só entra em vigor com ORDER BY.
SELECT id, vector <#> '1,1,1'::pase AS distance
FROM table_name
ORDER BY
vector <#> '1,1,1:10:0'::pase
ASC LIMIT 10;
O formato da string de consulta é vector:n:similarity_method:
n: número de clusters a pesquisar, intervalo(0, 1000]. Valores maiores melhoram o recall às custas da velocidade. Ajuste conforme seus requisitos de recall e latência.similarity_method:0= distância euclidiana,1= produto escalar (requer vetores normalizados).
Consulta HNSW
Use o operador <?> e inclua ORDER BY.
SELECT id, vector <?> '1,1,1'::pase AS distance
FROM table_name
ORDER BY
vector <?> '1,1,1:100:0'::pase
ASC LIMIT 10;
O formato da string de consulta é vector:ef:similarity_method:
ef: tamanho do heap de candidatos durante a consulta, intervalo(0, ∞). Comece com40e aumente em pequenos incrementos até encontrar o equilíbrio ideal para sua carga de trabalho.similarity_method:0= distância euclidiana,1= produto escalar (requer vetores normalizados).
Observações de uso
Inchaço do índice: Verifique o tamanho do índice com
SELECT pg_relation_size('index_name');e compare-o com o tamanho da tabela. Se o índice estiver maior que a tabela e as consultas ficarem mais lentas, reconstrua o índice.Perda de precisão após atualizações: Atualizações frequentes de dados podem deixar o índice desatualizado. Caso seja necessário recall de 100%, reconstrua o índice regularmente.
Criação de índice IVFFlat com centroides internos: Defina
clustering_type = 1e certifique-se de que a tabela já contenha dados antes de criar o índice.
Exemplo: Fluxo completo com IVFFlat
Este exemplo cria uma tabela, carrega vetores tridimensionais, constrói um índice IVFFlat e executa uma consulta de vizinhos mais próximos.
-- Step 1: Enable the extension
CREATE EXTENSION pase;
-- Step 2: Create the table
CREATE TABLE vectors_table (
id SERIAL PRIMARY KEY,
vector float4[] NOT NULL
);
-- Step 3: Insert sample data
INSERT INTO vectors_table (vector) VALUES
('{1.0, 0.0, 0.0}'),
('{0.0, 1.0, 0.0}'),
('{0.0, 0.0, 1.0}'),
('{0.0, 0.5, 0.0}'),
('{0.0, 0.5, 0.0}'),
('{0.0, 0.6, 0.0}'),
('{0.0, 0.7, 0.0}'),
('{0.0, 0.8, 0.0}'),
('{0.0, 0.0, 0.0}');
-- Step 4: Build the IVFFlat index
CREATE INDEX ivfflat_idx ON vectors_table
USING
pase_ivfflat(vector)
WITH
(clustering_type = 1, distance_type = 0, dimension = 3, base64_encoded = 0, clustering_params = "10,100");
-- Step 5: Query the 10 nearest neighbors to [1, 1, 1]
SELECT id, vector <#> '1,1,1'::pase AS distance
FROM vectors_table
ORDER BY
vector <#> '1,1,1:10:0'::pase
ASC LIMIT 10;
Apêndice
Cálculo de produto escalar ou similaridade de cosseno
O produto escalar de um vetor normalizado equivale ao seu valor de cosseno. Esta função usa um índice HNSW para recuperar os top-k resultados por produto escalar:
CREATE OR REPLACE FUNCTION inner_product_search(
query_vector text,
ef integer,
k integer,
table_name text
)
RETURNS TABLE (id integer, uid text, distance float4) AS $$
BEGIN
RETURN QUERY EXECUTE format('
SELECT a.id, a.vector <?> pase(ARRAY[%s], %s, 1) AS distance
FROM (
SELECT id, vector
FROM %s
ORDER BY vector <?> pase(ARRAY[%s], %s, 0) ASC
LIMIT %s
) a
ORDER BY distance DESC;',
query_vector, ef, table_name, query_vector, ef, k
);
END
$$ LANGUAGE plpgsql;
Uso de arquivo de centroides externo para IVFFlat
Esta é uma opção avançada. Carregue um arquivo de centroides externo no diretório do servidor e referencie-o em clustering_params quando clustering_type = 0. O formato do arquivo é:
Number of dimensions|Number of centroids|Centroid vector dataset
Exemplo:
3|2|1,1,1,2,2,2
Referências
Product Quantization for Nearest Neighbor Search — Hervé Jégou, Matthijs Douze, Cordelia Schmid
Efficient and robust approximate nearest neighbor search using Hierarchical Navigable Small World graphs — Yu.A. Malkov, D.A. Yashunin