【发布时间】:2026-02-03 22:25:01
【问题描述】:
所以我有一个包含 500 万行多一点的表。当我使用 SQL_CALC_FOUND_ROWS 时,查询会永远挂起。当我把它拿出来时,查询会在一秒钟内执行 LIMIT ,25。我的问题是出于分页原因,是否有替代方法来获取总行数?
【问题讨论】:
标签: mysql pagination sql-calc-found-rows
所以我有一个包含 500 万行多一点的表。当我使用 SQL_CALC_FOUND_ROWS 时,查询会永远挂起。当我把它拿出来时,查询会在一秒钟内执行 LIMIT ,25。我的问题是出于分页原因,是否有替代方法来获取总行数?
【问题讨论】:
标签: mysql pagination sql-calc-found-rows
SQL_CALC_FOUND_ROWS 强制 MySQL 扫描所有匹配的行,即使它们永远不会被获取。在内部,它相当于在没有 LIMIT 子句的情况下执行相同的查询。
如果您通过 WHERE 进行的过滤不是太疯狂,您可以计算并缓存各种类型的过滤器以节省 calc_found_rows 施加的全扫描负载。对于大多数可能的 where 子句,基本上运行“select count(*) from ... where ....”。
否则,您可以采用 Google 的方式,只是吐出一些偶尔与现实无关的页码(您知道,您会看到“Gooooooooooooogle”,进入第 3 页,然后突然用完结果)。
【讨论】:
SQL_CALC_FOUND_ROWS 还是从我的查询中删除 LIMIT 子句。从您的回答来看,您似乎是在说这些应该执行相同的操作。这是一个安全的假设,还是比这更复杂?谢谢。
详细谈谈实现谷歌风格pagination using MySQL
【讨论】:
您应该根据情况在 COUNT(*) 和 SQL_CALC_FOUND_ROWS 之间进行选择。如果您的查询搜索条件使用索引中的行 - 使用 COUNT(*)。在这种情况下,Mysql 将仅从索引中“读取”而不接触表中的实际数据,而 SQL_CALC_FOUND_ROWS 方法将从磁盘加载行,这在海量表上可能是昂贵且耗时的。
this article @mysqlperformanceblog 中有关此主题的更多信息。
【讨论】: