MySQL has started deprecating SQL_CALC_FOUND_ROWS
functionality with version 8.0.17 onwards.
So, it is always preferred to consider executing your query with LIMIT
, and then a second query with COUNT(*)
and without LIMIT
to determine whether there are additional rows.
From docs:
The SQL_CALC_FOUND_ROWS query modifier and accompanying FOUND_ROWS()
function are deprecated as of MySQL 8.0.17 and will be removed in a
future MySQL version.
COUNT(*) is subject to certain optimizations. SQL_CALC_FOUND_ROWS
causes some optimizations to be disabled.
Use these queries instead:
SELECT * FROM tbl_name WHERE id > 100 LIMIT 10;
SELECT COUNT(*) WHERE id > 100;
Also, SQL_CALC_FOUND_ROWS
has been observed to having more issues generally, as explained in the MySQL WL# 12615 :
SQL_CALC_FOUND_ROWS has a number of problems. First of all, it's slow.
Frequently, it would be cheaper to run the query with LIMIT and then a
separate SELECT COUNT() for the same query, since COUNT() can make
use of optimizations that can't be done when searching for the entire
result set (e.g. filesort can be skipped for COUNT(*), whereas with
CALC_FOUND_ROWS, we must disable some filesort optimizations to
guarantee the right result)
More importantly, it has very unclear semantics in a number of
situations. In particular, when a query has multiple query blocks
(e.g. with UNION), there's simply no way to calculate the number of
“would-have-been” rows at the same time as producing a valid query. As
the iterator executor is progressing towards these kinds of queries,
it is genuinely difficult to try to retain the same semantics.
Furthermore, if there are multiple LIMITs in the query (e.g. for
derived tables), it's not necessarily clear to which of them
SQL_CALC_FOUND_ROWS should refer to. Thus, such nontrivial queries
will necessarily get different semantics in the iterator executor
compared to what they had before.
Finally, most of the use cases where SQL_CALC_FOUND_ROWS would seem
useful should simply be solved by other mechanisms than LIMIT/OFFSET.
E.g., a phone book should be paginated by letter (both in terms of UX
and in terms of index use), not by record number. Discussions are
increasingly infinite-scroll ordered by date (again allowing index
use), not by paginated by post number. And so on.
SQL_CALC_FOUND_ROWS
took over 20 seconds; using a separateCOUNT(*)
query took under 5 seconds (for both count + results queries). – Froufrou