Crie um índice ScaNN

Esta página descreve como usar incorporações armazenadas para gerar índices e consultar incorporações usando o índice ScaNN com o AlloyDB for PostgreSQL. Para mais informações sobre o armazenamento de incorporações, consulte o artigo Armazene incorporações de vetores.

AlloyDB alloydb_scann, uma extensão do PostgreSQL desenvolvida pela Google que implementa um índice de vizinhos mais próximos altamente eficiente com tecnologia do algoritmo ScaNN.

O índice ScaNN é um índice de quantização baseado em árvores para a pesquisa aproximada do vizinho mais próximo. Oferece um tempo de criação de índice mais baixo e uma menor ocupação de memória em comparação com o HNSW. Além disso, oferece QPS mais rápidas em comparação com o HNSW com base na carga de trabalho.

Antes de começar

Antes de poder começar a criar índices, tem de concluir os seguintes pré-requisitos.

  • Os vetores de incorporação são adicionados a uma tabela na sua base de dados do AlloyDB.

  • A extensão vector baseada em pgvector, expandida pela Google para o AlloyDB, e a extensão alloydb_scann estão instaladas:

    CREATE EXTENSION IF NOT EXISTS alloydb_scann CASCADE;
    
  • Se quiser criar índices ScaNN otimizados automaticamente, certifique-se de que a flag scann.enable_preview_features está ativada. Se não quiser ativar as funcionalidades de pré-visualização ou para instâncias de produção, pode criar um índice ScaNN com parâmetros específicos.

Crie um índice ScaNN ajustado automaticamente

Com a funcionalidade de indexação automática, pode simplificar a criação de índices para criar automaticamente índices otimizados para o desempenho da pesquisa ou tempos de compilação de índices equilibrados e desempenho da pesquisa.

Quando usa o modo AUTO, só tem de especificar o nome da tabela e a coluna de incorporação, juntamente com a função de distância que quer usar. Pode otimizar o índice para o desempenho da pesquisa ou equilibrar os tempos de criação do índice e o desempenho da pesquisa.

Também existe uma opção para usar o modo MANUAL para criar índices com controlo detalhado sobre outros parâmetros de otimização de índices.

Crie um índice ScaNN no modo AUTO

Seguem-se alguns pontos a ter em atenção antes de criar índices no modo AUTO:

  • O AlloyDB não consegue criar um índice ScaNN para tabelas com dados insuficientes.
  • Não pode definir parâmetros de criação de índices, como num_leaves, quando cria índices no modo AUTO.
  • A manutenção automática está ativada por predefinição para todos os índices criados no modo AUTO.

Para criar um índice no modo AUTO, ative primeiro a flag de funcionalidade scann.zero_knob_index_creation. Depois de ativar o sinalizador, execute o seguinte comando:

      CREATE INDEX INDEX_NAME ON TABLE \
      USING scann (EMBEDDING_COLUMN DISTANCE_FUNCTION) \
      WITH (mode=AUTO', optimization='OPTIMIZATION');

Substitua o seguinte:

  • INDEX_NAME: o nome do índice que quer criar, por exemplo, my-scann-index. Os nomes dos índices são partilhados em toda a base de dados. Verifique se cada nome de índice é exclusivo para cada tabela na sua base de dados.

  • TABLE: a tabela à qual adicionar o índice.

  • EMBEDDING_COLUMN: a coluna que armazena dados de vector

  • DISTANCE_FUNCTION: a função de distância a usar com este índice. Selecione uma das seguintes opções:

    • Distância L2: l2

    • Produto escalar: dot_product

    • Distância do cosseno: cosine

  • OPTIMIZATION: defina como uma das seguintes opções:

    • SEARCH_OPTIMIZED: para otimizar a capacidade de resposta da pesquisa vetorial e a latência da pesquisa vetorial a um custo de maior tempo de criação do índice.
    • BALANCED: para criar um índice que equilibre o tempo de criação do índice e o desempenho da pesquisa.

Crie um índice ScaNN no modo MANUAL

Se ativou a flag scann.enable_preview_features e quiser um controlo detalhado sobre os parâmetros de otimização, pode criar o índice no modo MANUAL.

Para criar um índice ScaNN no modo MANUAL, execute o seguinte comando:

      CREATE INDEX INDEX_NAME ON TABLE \
      USING scann (EMBEDDING_COLUMN DISTANCE_FUNCTION) \
      WITH (mode='MANUAL, num_leaves=NUM_LEAVES_VALUE, [quantizer =QUANTIZER, max_num_levels=MAX_NUM_LEVELS]);

Substitua o seguinte:

  • INDEX_NAME: o nome do índice que quer criar, por exemplo, my-scann-index. Os nomes dos índices são partilhados em toda a base de dados. Verifique se cada nome de índice é exclusivo para cada tabela na sua base de dados.

  • TABLE: a tabela à qual adicionar o índice.

  • EMBEDDING_COLUMN: a coluna que armazena dados de vector

  • DISTANCE_FUNCTION: a função de distância a usar com este índice. Selecione uma das seguintes opções:

    • Distância L2: l2

    • Produto escalar: dot_product

    • Distância do cosseno: cosine

  • NUM_LEAVES_VALUE: o número de partições a aplicar a este índice. Defina qualquer valor entre 1 e 1048576.

  • QUANTIZER: o tipo de quantizador a usar. As opções disponíveis são as seguintes:

    • SQ8: oferece um equilíbrio entre o desempenho das consultas e a perda mínima de capacidade de memorização, normalmente inferior a 1 a 2%. Este é o valor predefinido.
    • AH: considere esta opção para um desempenho de consulta potencialmente melhor quando o motor de colunas estiver ativado e os dados de índice e tabela forem preenchidos no motor de colunas, sujeitos ao respetivo tamanho configurado. Tenha em atenção que o formato AH é até 4 vezes mais comprimido do que o formato SQ8. Para mais informações, consulte o artigo Práticas recomendadas para otimizar o ScaNN.
    • FLAT: oferece a maior capacidade de memorização de 99% ou superior à custa do desempenho da pesquisa.
  • MAX_NUM_LEVELS: o número máximo de níveis da árvore de agrupamento K-means. Defina como 1(predefinição) para a quantização baseada em árvore de dois níveis e defina como 2 para a quantização baseada em árvore de três níveis.

Pode adicionar outros parâmetros de criação de índice ou de tempo de execução de consultas para otimizar o índice. Para mais informações, consulte o artigo Ajuste um índice ScaNN.

Altere os modos dos índices existentes

Se criou um índice ScaNN usando o modo AUTO e quiser otimizar o índice manualmente, tem de alterar o modo para MANUAL.

Para alterar o modo para MANUAL, siga estes passos:

  1. Atualize o índice para definir o modo como MANUAL:

    ALTER INDEX INDEX_NAME SET (mode = 'MANUAL', num_leaves = NUM_LEAVES_VALUE);
    

    Substitua o seguinte:

    • INDEX_NAME: o nome do índice que quer criar, por exemplo, my-scann-index. Os nomes dos índices são partilhados na sua base de dados. Verifique se cada nome de índice é exclusivo para cada tabela na sua base de dados.

    • NUM_LEAVES_VALUE: o número de partições a aplicar a este índice. Defina qualquer valor entre 1 e 1048576.

    Pode adicionar outros parâmetros de criação de índice ou de tempo de execução de consultas para otimizar o índice. Para mais informações, consulte o artigo Ajuste um índice ScaNN.

  2. Recompile o índice para aplicar os parâmetros:

    REINDEX INDEX CONCURRENTLY INDEX_NAME;
    

Para alterar o modo para AUTO, conclua os seguintes passos:

  1. Atualize o índice para definir o modo como AUTO:

    ALTER INDEX INDEX_NAME SET (mode = 'AUTO');
    
  2. Recompile o índice para aplicar os parâmetros:

    REINDEX INDEX CONCURRENTLY INDEX_NAME;
    

Crie um índice ScaNN com parâmetros específicos

Se a sua aplicação tiver requisitos específicos para tempos de criação de índice e de recolha, pode criar o índice manualmente. Pode criar um índice de árvore de dois ou três níveis com base na sua carga de trabalho. Para mais informações sobre a otimização dos parâmetros, consulte o artigo Otimize um ScaNNíndice.

Índice de árvore de dois níveis

Para aplicar um índice de árvore de dois níveis usando o algoritmo ScaNN a uma coluna que contenha incorporações de vetores armazenadas, execute a seguinte consulta DDL:

CREATE INDEX INDEX_NAME ON TABLE
  USING scann (EMBEDDING_COLUMN DISTANCE_FUNCTION)
  WITH (num_leaves=NUM_LEAVES_VALUE, quantizer =QUANTIZER);

Substitua o seguinte:

  • INDEX_NAME: o nome do índice que quer criar, por exemplo, my-scann-index. Os nomes dos índices são partilhados na sua base de dados. Certifique-se de que cada nome de índice é exclusivo para cada tabela na sua base de dados.

  • TABLE: a tabela à qual adicionar o índice.

  • EMBEDDING_COLUMN: uma coluna que armazena vector dados.

  • DISTANCE_FUNCTION: a função de distância a usar com este índice. Selecione uma das seguintes opções:

    • Distância L2: l2

    • Produto escalar: dot_product

    • Distância do cosseno: cosine

  • NUM_LEAVES_VALUE: o número de partições a aplicar a este índice. Defina qualquer valor entre 1 e 1048576. Para mais informações sobre como decidir este valor, consulte o artigo Ajuste um índice ScaNN.

  • QUANTIZER: o tipo de quantizador a usar. As opções disponíveis são as seguintes:

    • SQ8: oferece um equilíbrio entre o desempenho das consultas e a perda mínima de capacidade de memorização, normalmente inferior a 1 a 2%. Este é o valor predefinido.
    • AH: considere esta opção para um desempenho de consulta potencialmente melhor quando o motor de colunas estiver ativado e os dados de índice e tabela forem preenchidos no motor de colunas, sujeitos ao respetivo tamanho configurado. Tenha em atenção que o formato AH é até 4 vezes mais comprimido do que o formato SQ8. Para mais informações, consulte o artigo Práticas recomendadas para otimizar o ScaNN.
    • FLAT: oferece a maior capacidade de memorização de 99% ou superior à custa do desempenho da pesquisa.

Índice de árvore de três níveis

Para criar um índice de árvore de três níveis usando o algoritmo ScaNN numa coluna que contenha incorporações de vetores armazenadas, execute a seguinte consulta DDL:

CREATE INDEX INDEX_NAME ON TABLE
  USING scann (EMBEDDING_COLUMN DISTANCE_FUNCTION)
  WITH (num_leaves=NUM_LEAVES_VALUE, max_num_levels = 2);

Depois de criar o índice, pode executar consultas de pesquisa de vizinhos mais próximos que usam o índice seguindo as instruções em Faça uma consulta de vizinhos mais próximos com um determinado texto.

Os parâmetros de índice têm de ser definidos para encontrar o equilíbrio certo entre as consultas por segundo e a capacidade de memorização. Para mais informações sobre a otimização do índice ScaNN, consulte o artigo Otimize um ScaNN índice.

Para criar este índice numa coluna de incorporação que usa o tipo de dados real[] em vez de vector, converta a coluna no tipo de dados vector:

CREATE INDEX INDEX_NAME ON TABLE
  USING scann (CAST(EMBEDDING_COLUMN AS vector(DIMENSIONS)) DISTANCE_FUNCTION)
  WITH (num_leaves=NUM_LEAVES_VALUE, max_num_levels = MAX_NUM_LEVELS);

Substitua DIMENSIONS pela largura dimensional da coluna de incorporação. Para mais informações sobre como encontrar as dimensões, consulte a função vector_dims em Funções vetoriais.

Para conseguir uma experiência de pesquisa consistente, ative a manutenção automática quando criar um índice ScaNN. Para mais informações, consulte o artigo Mantenha os índices de vetores. Esta funcionalidade está disponível na pré-visualização.

Para ver o progresso da indexação, use a vista pg_stat_progress_create_index:

SELECT * FROM pg_stat_progress_create_index;

A coluna phase mostra o estado atual da criação do índice. Após a conclusão da fase de criação do índice, a linha do índice não fica visível.

Para ajustar o índice de modo a ter um equilíbrio médio entre a capacidade de memorização e as consultas por segundo, consulte o artigo Ajuste um índice ScaNN.

Crie índices em paralelo

Para criar o índice mais rapidamente, o AlloyDB pode gerar automaticamente vários trabalhadores paralelos, consoante o conjunto de dados e o tipo de índice que escolher.

A criação de índice paralela é frequentemente acionada se estiver a criar um índice ScaNN de 3 níveis ou se o seu conjunto de dados exceder 100 milhões de linhas.

Embora o AlloyDB otimize automaticamente o número de trabalhadores paralelos, pode ajustar os trabalhadores paralelos através dos parâmetros de planeamento de consultas do PostgreSQL max_parallel_maintenance_workers, max_parallel_workers e min_parallel_table_scan_size.

Execute uma consulta

Depois de armazenar e indexar as incorporações na base de dados, pode começar a consultar os seus dados. Não pode executar consultas de pesquisa em massa através da extensão alloydb_scann.

Para encontrar os vizinhos semânticos mais próximos de um vetor de incorporação, pode executar a consulta de exemplo seguinte, em que define a mesma função de distância que usou durante a criação do índice.

  SELECT * FROM TABLE
    ORDER BY EMBEDDING_COLUMN DISTANCE_FUNCTION_QUERY ['EMBEDDING']
    LIMIT ROW_COUNT

Substitua o seguinte:

  • TABLE: a tabela que contém a incorporação com a qual comparar o texto.

  • INDEX_NAME: o nome do índice que quer usar, por exemplo, my-scann-index.

  • EMBEDDING_COLUMN: a coluna que contém as incorporações armazenadas.

  • DISTANCE_FUNCTION_QUERY: a função de distância a usar com esta consulta. Escolha uma das seguintes opções com base na função de distância usada ao criar o índice:

    • Distância L2: <->

    • Produto interior: <#>

    • Distância do cosseno: <=>

  • EMBEDDING: o vetor de incorporação para o qual quer encontrar os vizinhos semânticos armazenados mais próximos.

  • ROW_COUNT: o número de linhas a devolver.

    Especifique 1 se quiser apenas a melhor correspondência única.

Também pode usar a função embedding() para traduzir o texto num vetor. Uma vez que embedding() devolve uma matriz real, tem de converter explicitamente a chamada embedding() em vector antes de a aplicar a um dos operadores de vizinhos mais próximos (por exemplo, <-> para a distância L2). Em seguida, estes operadores podem usar o índice ScaNN para encontrar as linhas da base de dados com as incorporações semanticamente mais semelhantes.

O que se segue?