Exécuter une requête avec un LIMIT/OFFSET et aussi obtenir le nombre total de lignes
Fins de mise en page, j'ai besoin d'une exécution d'une requête avec le LIMIT
et OFFSET
clauses. Mais j'ai aussi besoin d'un comptage du nombre de lignes qui seraient renvoyées par la requête sans le LIMIT
et OFFSET
clauses.
Je veux courir:
SELECT * FROM table WHERE /* whatever */ ORDER BY col1 LIMIT ? OFFSET ?
Et:
SELECT COUNT(*) FROM table WHERE /* whatever */
En même temps. Est-il un moyen de le faire, en particulier d'une manière qui permet à Postgres l'optimiser, de sorte qu'il est plus rapide que de courir à la fois individuellement?
Vous devez vous connecter pour publier un commentaire.
Oui. Avec une simple fonction de fenêtre:
Être conscient que le coût sera sensiblement plus élevé que sans le nombre total, mais toujours moins cher que les deux requêtes distinctes. Postgres a fait compter toutes les lignes dans les deux cas, ce qui impose un coût en fonction du nombre total de lignes de qualification. Détails:
Cependant, comme Dani souligné, quand
OFFSET
est au moins aussi grand que le nombre de lignes retournées par la requête de base, aucune ligne n'est retournée. Donc, nous aussi, ne pas obtenir lefull_count
.Si ce n'est pas acceptable, d'un possible solution de contournement qui renvoie toujours le plein comte serait avec une expression de table commune et un
OUTER JOIN
:Vous obtenez une rangée de valeurs NULL avec le
full_count
ajoutée siOFFSET
est trop grand. Ou il est annexé à chaque ligne comme dans la première requête.Si une ligne avec toutes les valeurs NULL est un possible résultat valide, vous devez vérifier
offset >= full_count
pour lever l'ambiguïté sur l'origine de la ligne vide.Ce encore exécute la requête de base qu'une seule fois. Mais il ajoute plus généraux de la requête et ne paie que si c'est moins que de répéter la requête de base pour le nombre de.
Si les indices de l'appui de la finale de l'ordre de tri sont disponibles, il pourrait payer pour inclure le
ORDER BY
dans le CTE (redondance).Ses mauvaises pratiques d'appeler deux fois la même requête pour obtenir Juste le nombre total de lignes de la returend résultat. Il faudra du temps d'exécution et de déchets de l'server ressource.
Mieux, vous pouvez utiliser
SQL_CALC_FOUND_ROWS
dans la requête qui permet de dire à MySQL pour récupérer le nombre total de nombre de lignes le long de la limite des résultats de la requête.Exemple définir comme:
Dans la Requête ci-dessus, il suffit d'ajouter
SQL_CALC_FOUND_ROWS
option dans le reste nécessaire de requête et d'exécuter la deuxième ligne, c'est à direSELECT FOUND_ROWS()
retourne le nombre de lignes dans le jeu de résultats retournés par cette déclaration.Pas.
Il y a peut-être quelques petites gain vous pourriez théoriquement gain sur l'exécution individuellement avec assez de machines compliquées sous le capot. Mais, si vous voulez savoir combien de lignes correspondent à une condition, vous aurez à les compter, plutôt que de simplement un sous-ensemble Limité.