Realiza una recuperación Top-K eficiente

Muchas aplicaciones consultan una base de datos para propagar una sola página en sus aplicaciones. En esas aplicaciones, la aplicación no necesita todas las coincidencias, sino solo las coincidencias Top-K según el orden de clasificación del índice. Los índices de búsqueda pueden implementar este tipo de búsqueda de manera muy eficiente. En esta página, se describe cómo crear y buscar un índice que tenga coincidencias Top-K.

Crea índices de búsqueda para coincidencias Top-K

Para configurar un índice de búsqueda para la coincidencia de Top-K, usa ORDER BY para ordenar el índice de búsqueda por una columna específica. Las consultas deben tener una cláusula ORDER BY que coincida exactamente con el orden de clasificación del índice de búsqueda (incluida la dirección ascendente o descendente) y una cláusula LIMIT que solicite que la consulta se detenga después de encontrar filas que coincidan con k.

También puedes implementar la paginación con estas cláusulas. Para obtener más información, consulta Cómo paginar las búsquedas.

En algunos casos de uso, podría tener sentido mantener varios índices de búsqueda ordenados por diferentes columnas. Al igual que la partición, es una compensación entre el almacenamiento y el costo de escritura en comparación con la latencia de consulta.

Por ejemplo, considera una tabla que usa el siguiente esquema:

GoogleSQL

CREATE TABLE Albums (
  AlbumId STRING(MAX) NOT NULL,
  RecordTimestamp INT64 NOT NULL,
  ReleaseTimestamp INT64 NOT NULL,
  ListenTimestamp INT64 NOT NULL,
  AlbumTitle STRING(MAX),
  AlbumTitle_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(AlbumTitle)) HIDDEN
) PRIMARY KEY(AlbumId);

CREATE SEARCH INDEX AlbumsRecordTimestampIndex
ON Albums(AlbumTitle_Tokens, SingerId_Tokens)
STORING (ListenTimestamp)
ORDER BY RecordTimestamp DESC

CREATE SEARCH INDEX AlbumsReleaseTimestampIndex
ON Albums(AlbumTitle_Tokens)
STORING (ListenTimestamp)
ORDER BY ReleaseTimestamp DESC

PostgreSQL

CREATE TABLE albums (
  albumid character varying NOT NULL,
  recordtimestamp bigint NOT NULL,
  releasetimestamp bigint NOT NULL,
  listentimestamp bigint NOT NULL,
  albumtitle character varying,
  albumtitle_tokens spanner.tokenlist
      GENERATED ALWAYS AS (spanner.tokenize_fulltext(albumtitle)) VIRTUAL HIDDEN,
PRIMARY KEY(albumid));

CREATE SEARCH INDEX albumsrecordtimestampindex
ON Albums(albumtitle_tokens, singerid_tokens)
INCLUDE (listentimestamp)
ORDER BY recordtimestamp DESC

CREATE SEARCH INDEX albumsreleasetimestampindex
ON Albums(albumtitle_tokens)
INCLUDE (listentimestamp)
ORDER BY releasetimestamp DESC

Consulta los índices de búsqueda para las coincidencias de Top-K

Como se indicó anteriormente, las consultas deben tener una cláusula ORDER BY que coincida exactamente con el orden de clasificación del índice de búsqueda (incluida la dirección ascendente o descendente) y una cláusula LIMIT que solicite que la consulta se detenga después de encontrar filas que coincidan con k.

En la siguiente lista, se analiza la eficiencia de algunas consultas comunes.

  • Esta consulta es muy eficiente. Selecciona el índice AlbumsRecordTimestampIndex. Incluso si hay muchos álbumes con la palabra "feliz", la consulta solo analiza una pequeña cantidad de filas:

    GoogleSQL

    SELECT AlbumId
    FROM Albums
    WHERE SEARCH(AlbumTitle_Tokens, 'happy')
    ORDER BY RecordTimestamp DESC
    LIMIT 10
    

    PostgreSQL

    SELECT albumid
    FROM albums
    WHERE spanner.search(albumtitle_tokens, 'happy')
    ORDER BY recordtimestamp DESC
    LIMIT 10
    
  • La misma consulta, que solicita el orden de clasificación por ReleaseTimestamp en orden descendente, usa el índice AlbumsReleaseTimestampIndex y es igualmente eficiente:

    GoogleSQL

    SELECT AlbumId
    FROM Albums
    WHERE SEARCH(AlbumTitle_Tokens, 'happy')
    ORDER BY ReleaseTimestamp DESC
    LIMIT 10
    

    PostgreSQL

    SELECT albumid
    FROM albums
    WHERE spanner.search(albumtitle_tokens, 'happy')
    ORDER BY releasetimestamp DESC
    LIMIT 10
    
  • Una consulta que solicita el orden de clasificación por ListenTimestamp no ejecuta una consulta Top-K de manera eficiente. Debe recuperar todos los álbumes que coincidan, ordenarlos por ListenTimestamp, y mostrar los 10 principales. Una consulta de este tipo usa más recursos si hay una gran cantidad de documentos que contienen el término “feliz”.

    GoogleSQL

    SELECT AlbumId
    FROM Albums
    WHERE SEARCH(AlbumTitle_Tokens, 'happy')
    ORDER BY ListenTimestamp DESC
    LIMIT 10
    

    PostgreSQL

    SELECT albumid
    FROM albums
    WHERE spanner.search(albumtitle_tokens, 'happy')
    ORDER BY listentimestamp DESC
    LIMIT 10
    
  • Del mismo modo, una consulta no se ejecuta de manera eficiente si solicita que los resultados se ordenen con la columna RecordTimestamp en orden ascendente. Analiza todas las filas con la palabra "happy", a pesar de tener un LIMIT.

    GoogleSQL

    SELECT AlbumId
    FROM Albums
    WHERE SEARCH(AlbumTitle_Tokens, 'happy')
    ORDER BY RecordTimestamp ASC
    LIMIT 10
    

    PostgreSQL

    SELECT albumid
    FROM albums
    WHERE spanner.search(albumtitle_tokens, 'happy')
    ORDER BY recordtimestamp ASC
    LIMIT 10
    

¿Qué sigue?