计算总数的最快方法,然后在MySQL中列出一组记录

时间:2009-10-13 20:15:15

标签: sql mysql performance

我有一个SQL语句来从表中选择结果。我需要知道找到的记录总数,然后列出它们的子集(分页)。

通常,我会进行2次SQL调用:

  1. 一个用于计算记录总数(使用COUNT),
  2. 另一个用于返回子集(使用LIMIT)。
  3. 但是,这样,你真的在​​MySQL上复制相同的操作:两个调用中的WHERE语句是相同的。

    有没有办法获得速度不重复MySQL上的选择?

7 个答案:

答案 0 :(得分:2)

第一个查询将导致数据被拉入缓存,因此可以推测第二个查询应该很快。我不会太担心这个。

答案 1 :(得分:1)

您必须同时进行两个SQL查询,并且COUNT非常快,没有WHERE子句。尽可能缓存数据。

答案 2 :(得分:0)

您应该只运行COUNT一次,然后将其缓存到某处。然后你可以根据需要运行分页查询。

答案 3 :(得分:0)

如果确实不想运行COUNT()查询 - 并且正如其他人所说的那样,那不是让事情明显减慢的事情 - 那么你必须决定你的大块预设大小(即LIMIT号码)。这将为您保存COUNT()查询,但最终可能会出现不幸的分页结果(如2页,其中第2页只有1个结果)。

因此,快速COUNT()然后是明智的LIMIT设置,或者没有COUNT()和任意LIMIT可能会增加更贵的查询数量必须这样做。

答案 4 :(得分:0)

您可以尝试只选择一个字段(比如ID),看看是否有帮助,但我认为不会 - 我想最大的开销是MySQL首先找到正确的行。

如果您只想计算整个表格中的总行数(即没有WHERE子句),那么我相信SELECT COUNT(*) FROM table非常有效。

否则,如果您需要显示总数,唯一的解决方案是选择所有行。但是,您可以将其缓存在另一个表中。如果您从某个类别中选择某些内容,例如,请存储类别UID和所选的总行数。然后,无论何时添加/删除行,都要再次计算总数。

另一种选择 - 尽管可能会牺牲一点可用性 - 只是选择当前页面和下一页所需的行。如果下一页有可用的行,请添加“下一步”链接。对上一页做同样的事情。如果每页有20行,则每次加载页面时最多选择60行,并且不需要计算所有可用行。

答案 5 :(得分:0)

如果您编写查询以包含一个包含计数的列(在每一行中),然后包含第二个查询中的其余列,您可以:

  1. 避免第二次数据库往返(这可能比你的查询更昂贵)
  2. 增加MySQL解析器生成重用基本查询的优化执行计划的可能性。
  3. 使操作成为原子。
  4. 不幸的是,它还会产生一些重复,返回的数据超出了您真正需要的数量。但无论如何,我希望它会更有效率。这是许多ORM产品在急切地从具有多对一或多对多关系的连接表中加载对象时使用的策略。

答案 6 :(得分:0)

正如其他人已经指出的那样,在这种情况下可能不值得关注 - 只要“字段”被编入索引,两个选择都会非常快。

如果您(无论出于何种原因)某种情况还不够,您可以创建一个基于内存的临时表(即由内存存储引擎支持的临时表),并将您的记录选择到该临时表中。然后你可以从临时表中做出选择并且非常确定它们会很快。这可以使用大量的内存(即它会强制数据全部停留在内存中),所以除非你确定:

,否则它非常不友好。
  1. 数据量非常小;
  2. 你有这么多记忆并不重要;或
  3. 无论如何,机器将几乎闲置。

这个派上用场的主要时间是你有一个非常复杂的选择,无法避免扫描所有大表(或多个表),但只产生少量数据。