Les applications Web paginent souvent les données telles qu'elles sont présentées aux utilisateurs. L'utilisateur final reçoit une page de résultats. Lorsqu'il accède à la page suivante, le lot suivant de résultats est récupéré et présenté. Cette page explique comment ajouter la pagination aux résultats de recherche lorsque vous effectuez une recherche en texte intégral dans Spanner.
Présentation
Il existe deux façons d'implémenter des requêtes paginées dans Spanner: pagination basée sur des clés (recommandée) et pagination basée sur les décalages.
La pagination basée sur des clés est une méthode permettant de récupérer les résultats de recherche en blocs plus petits et plus faciles à gérer, tout en garantissant des résultats cohérents entre les requêtes. Un identifiant unique (la "clé") du dernier résultat d'une page est utilisé comme point de référence pour extraire l'ensemble de résultats suivant.
Spanner recommande généralement d'utiliser la pagination basée sur les clés. Alors que la pagination basée sur le décalage est plus facile à implémenter, car elle comporte deux éléments importants drawbacks:
- Coût des requêtes plus élevé:la pagination basée sur décalage récupère et récupère de manière répétée écarte les mêmes résultats, ce qui entraîne une augmentation des coûts et une diminution des performances.
- Résultats incohérents : dans les requêtes paginées, chaque page est généralement récupérée à un code temporel de lecture différent. Par exemple, la première page peut provenir d'une requête à 13h et la suivante d'une requête à 13h10. Cela signifie que les résultats de recherche changent d'une requête à l'autre, ce qui entraîne des incohérences sur les différentes pages.
La pagination basée sur une clé, en revanche, utilise un identifiant unique (clé) du dernier résultat d'une page pour récupérer l'ensemble de résultats suivant. Cela garantit une récupération efficace et des résultats cohérents, même si les données sous-jacentes changent.
Pour assurer la stabilité des résultats de page, l'application peut émettre toutes les requêtes pour différentes pages au même code temporel. Toutefois, cela peut échouer si la requête dépasse la durée de conservation des versions (par défaut, une heure). Par exemple, cette erreur se produit si version_gc
est égal à une heure, et que l'utilisateur final a extrait les premiers résultats à 13h et cliqué sur Suivant à 15h.
Utiliser la pagination basée sur une clé
La pagination basée sur une clé mémorise le dernier élément de la page précédente et l'utilise comme point de départ pour la requête de la page suivante. Pour ce faire, la requête doit renvoyer
colonnes spécifiées dans la clause ORDER BY
et limitez le nombre de lignes
avec LIMIT
.
Pour que la pagination basée sur les clés fonctionne, la requête doit classer les résultats selon des critères commande totale. Le moyen le plus simple d'obtenir un classement est de choisir un ordre total, puis d'ajouter des colonnes de départage, si nécessaire. Dans la plupart des cas, l'ordre total correspond à l'ordre de tri de l'index de recherche, et la combinaison unique de colonnes correspond à la clé primaire de la table de base.
Avec notre exemple de schéma Albums
, pour la première page, la requête se présente comme suit :
suivantes:
SELECT AlbumId, ReleaseTimestamp
FROM Albums
WHERE SEARCH(AlbumTitle_Tokens, "fifth symphony")
ORDER BY ReleaseTimestamp DESC, AlbumId
LIMIT 10;
AlbumId
permet de départager les égalités, puisque ReleaseTimestamp
n'est pas une clé. Il y
peut être deux albums différents avec la même valeur pour ReleaseTimestamp
.
Pour reprendre, l'application exécute à nouveau la même requête, mais avec une clause WHERE
qui limite les résultats de la page précédente. La condition supplémentaire
doit tenir compte de la direction clé (croissant ou décroissant), des conditions de départage,
et l'ordre des valeurs NULL pour les colonnes pouvant avoir une valeur nulle.
Dans notre exemple, AlbumId
est la seule colonne de clé (par ordre croissant) et ne peut pas être NULL. La condition est donc la suivante :
SELECT AlbumId, ReleaseTimestamp
FROM Albums
WHERE (ReleaseTimestamp < @last_page_release_timestamp
OR (ReleaseTimestamp = @last_page_release_timestamp
AND AlbumId > @last_page_album_id))
AND SEARCH(AlbumTitle_Tokens, @p)
ORDER BY ReleaseTimestamp DESC, AlbumId ASC
LIMIT @page_size;
Spanner interprète ce type de condition comme seekable. Cela signifie que Spanner ne lit pas l'index des documents que vous filtrez s'affiche. C'est cette optimisation qui rend la pagination basée sur les clés beaucoup plus efficace que la pagination basée sur les décalages.
Utiliser la pagination basée sur le décalage
La pagination basée sur le décalage exploite les clauses LIMIT
et OFFSET
des requêtes SQL.
pour simuler des pages. La valeur LIMIT
indique le nombre de résultats par page.
La valeur OFFSET
est définie sur zéro pour la première page, sur la taille de la page pour la deuxième page et sur le double de la taille de la page pour la troisième page.
Par exemple, la requête suivante extrait la troisième page, avec une taille de page de 50:
SELECT AlbumId
FROM Albums
WHERE SEARCH(AlbumTitle_Tokens, "fifth symphony")
ORDER BY ReleaseTimestamp DESC, AlbumId
LIMIT 50 OFFSET 100;
Remarques sur l'utilisation :
- La clause
ORDER BY
est vivement recommandée pour garantir un ordre cohérent. entre les pages. - Dans les requêtes de production, utilisez des paramètres de requête plutôt que des constantes pour spécifier
LIMIT
etOFFSET
pour rendre la mise en cache des requêtes plus efficace. Pour plus pour en savoir plus, consultez Paramètres de requête.
Étape suivante
- Découvrez comment classer les résultats de recherche.
- Découvrez comment effectuer une recherche de sous-chaîne.
- Découvrez comment combiner des requêtes de texte complet et non textuelles.
- Découvrez comment effectuer une recherche dans plusieurs colonnes.