MySQL a commencé à désapprouver les SQL_CALC_FOUND_ROWS
fonctionnalités à partir de la version 8.0.17.
Par conséquent, il est toujours préférable d'envisager d'exécuter votre requête avec LIMIT
, puis une deuxième requête avec COUNT(*)
et sans LIMIT
pour déterminer s'il existe des lignes supplémentaires.
À partir de la documentation :
Le modificateur de requête SQL_CALC_FOUND_ROWS et la fonction FOUND_ROWS () qui l'accompagne sont obsolètes à partir de MySQL 8.0.17 et seront supprimés dans une future version de MySQL.
COUNT (*) est soumis à certaines optimisations. SQL_CALC_FOUND_ROWS entraîne la désactivation de certaines optimisations.
Utilisez plutôt ces requêtes:
SELECT * FROM tbl_name WHERE id > 100 LIMIT 10;
SELECT COUNT(*) WHERE id > 100;
En outre, il SQL_CALC_FOUND_ROWS
a été observé avoir plus de problèmes en général, comme expliqué dans le MySQL WL # 12615 :
SQL_CALC_FOUND_ROWS a un certain nombre de problèmes. Tout d'abord, c'est lent. Souvent, il serait moins coûteux d'exécuter la requête avec LIMIT puis un SELECT COUNT ( ) séparé pour la même requête, car COUNT ( ) peut utiliser des optimisations qui ne peuvent pas être effectuées lors de la recherche de l'ensemble de résultats (par exemple, filesort peut être ignoré pour COUNT (*), alors qu'avec CALC_FOUND_ROWS, nous devons désactiver certaines optimisations de tri de fichiers pour garantir le bon résultat)
Plus important encore, sa sémantique est très floue dans un certain nombre de situations. En particulier, lorsqu'une requête a plusieurs blocs de requête (par exemple avec UNION), il n'y a tout simplement aucun moyen de calculer le nombre de lignes «aurait-il été» en même temps que de produire une requête valide. Au fur et à mesure que l'exécuteur de l'itérateur progresse vers ce type de requêtes, il est vraiment difficile d'essayer de conserver la même sémantique. De plus, s'il y a plusieurs LIMITs dans la requête (par exemple pour les tables dérivées), il n'est pas nécessairement clair à laquelle d'entre elles SQL_CALC_FOUND_ROWS doit se référer. Ainsi, de telles requêtes non triviales auront nécessairement une sémantique différente dans l'exécuteur de l'itérateur par rapport à ce qu'elles avaient auparavant.
Enfin, la plupart des cas d'utilisation où SQL_CALC_FOUND_ROWS semblerait utile devraient simplement être résolus par d'autres mécanismes que LIMIT / OFFSET. Par exemple, un annuaire téléphonique doit être paginé par lettre (à la fois en termes d'UX et en termes d'utilisation d'index), et non par numéro d'enregistrement. Les discussions sont de plus en plus organisées par défilement infini par date (permettant à nouveau l'utilisation de l'index), et non par pagination par numéro de poste. Etc.
SQL_CALC_FOUND_ROWS
pris plus de 20 secondes; l'utilisation d'uneCOUNT(*)
requête distincte a pris moins de 5 secondes (pour les requêtes de nombre + résultats)