【问题标题】:Find total number of results in mySQL query with offset+limit使用 offset+limit 在 mySQL 查询中查找结果总数
【发布时间】:2011-08-21 04:18:44
【问题描述】:

我正在使用 Codeigniter 进行分页功能,但我认为这通常适用于 PHP/mySQL 编码。

我正在使用偏移量和限制检索目录列表,具体取决于我想要每页有多少结果。但是要知道所需的总页数,我需要知道(结果总数)/(限制)。现在我正在考虑再次运行 SQL 查询,然后计算所需的行数,但不使用 LIMIT。但我认为这似乎是在浪费计算资源。

有没有更好的方法?谢谢!

编辑:我的 SQL 查询也使用 WHERE 来选择具有特定 'category_id' 的所有行

【问题讨论】:

  • 太棒了!!!感谢您的提问,不明白为什么它只有 23 票。这么基本的问题。
  • 这个问题标题更好,因为它首先出现:“如何检查mysql中是否使用了限制?” stackoverflow.com/q/28995579/1066234(重复)

标签: php mysql codeigniter pagination


【解决方案1】:

【讨论】:

  • 自 MySQL 8.0.17 起已弃用
  • 和MySQL提出的解决方案:只需使用两个查询,一个有LIMIT一个没有,见dev.mysql.com/doc/refman/8.0/en/…
  • 我查看了建议的 MySQL 8 后解决方案,这听起来通常是个坏主意。我想如果您使用LIMIT 的主要原因是分页一个太大而无法在内存中显示/保存的结果集,并且查询速度非常快,那会没问题。在所有其他情况下(例如改进慢查询),我们只剩下将整个结果集流式传输到客户端并在那里应用限制的解决方案。
【解决方案2】:

SELECT COUNT(*) FROM table_name WHERE column = 'value' 将很快返回表中匹配该条件的记录总数。

数据库SELECT 操作通常是“便宜的”(资源方面的),所以不要对以合理的方式使用它们感到难过。

编辑:在 OP 提到他们需要该功能之后添加了 WHERE

【讨论】:

  • 抱歉,我忘了补充一点,我的 SQL 查询也使用 WHERE 来选择具有特定 'category_id' 的所有行
  • nyx,SELECT COUNT(*) FROM table_name WHERE 条件是否仍然有效?
  • "SELECT 操作通常很便宜" - 如果您有数百万个数据库条目并且没有主索引和索引,则不会。小心。
【解决方案3】:

考虑到SQL_CALC_FOUND_ROWS 之后需要调用FOUND_ROWS(),如果您想使用从您的限制返回的结果获取总计数,而不必调用第二个SELECT,我会使用JOIN 结果来自subquery

SELECT * FROM `table` JOIN (SELECT COUNT(*) FROM `table` WHERE `category_id` = 9) t2 WHERE `category_id` = 9 LIMIT 50

注意:每个派生表都必须有自己的别名,因此请务必为连接表命名。在我的示例中,我使用了t2

【讨论】:

  • 我特别喜欢这个,因为它会访问数据库一次,但想知道它是否会比 2 个 SELECTs 更“昂贵”,因为它执行 JOIN,因为它是一个简单的 COUNT(*) .
  • 自 MySQL 8.0.17 起已弃用
【解决方案4】:

SQL_CALC_FOUND_ROWS 查询修饰符和随附的 FOUND_ROWS() 自 MySQL 8.0.17 起不推荐使用该函数,并将在 未来的 MySQL 版本。作为替代,考虑执行您的 使用 LIMIT 进行查询,然后使用 COUNT(*) 进行第二次查询,但不使用 LIMIT 来确定是否有额外的行。例如, 而不是这些查询:

SELECT SQL_CALC_FOUND_ROWS * FROM tbl_name WHERE id > 100 LIMIT 10;
SELECT FOUND_ROWS();

改用这些查询:

SELECT * FROM tbl_name WHERE id > 100 LIMIT 10;
SELECT COUNT(*) WHERE id > 100;

COUNT(*) 受到某些优化。 SQL_CALC_FOUND_ROWS 导致一些优化被禁用。

【讨论】:

  • 如果没有SQL_CALC_FOUND_ROWS,这似乎是一个不错的选择
【解决方案5】:

您可以使用以下 2 个查询,一个用于获取有限制的数据,另一个用于获取总匹配行数。

例如:

SELECT * FROM tbl_name WHERE id > 1000 LIMIT 10;
SELECT COUNT(*) FROM tbl_name WHERE id > 1000;

正如Mysql guide 所述,这是最优化的方式,并且SQL_CALC_FOUND_ROWS 查询修饰符和FOUND_ROWS() 函数已弃用自 MySQL 8.0.17 起

【讨论】:

    【解决方案6】:

    截至 2021 年决赛,为什么不呢:

    SELECT 
    t1.*, 
    COUNT(t1.*) OVER (PARTITION BY RowCounter) as TotalRecords
    FROM (
        SELECT a, b, c, 1 as RowCounter 
        FROM MyTable
    ) t1 
    LIMIT 120,10
    

    使用带有将每一行标记为相同值的列的子查询,将使我们能够使用 PARTITION BY 窗口函数组计算结果列的所有相同值

    【讨论】:

      【解决方案7】:
      SELECT COUNT(id) FROM `table` WHERE `category_id` = 9
      

      为您提供特定类别的行数。

      【讨论】:

      • SELECT COUNT(*) 性能更高,因为它不需要检查 NULL 值排除
      猜你喜欢
      • 2013-06-09
      • 2011-03-20
      • 2015-05-07
      • 2012-08-25
      • 1970-01-01
      • 2020-09-17
      • 1970-01-01
      • 1970-01-01
      • 2012-07-28
      相关资源
      最近更新 更多