【发布时间】:2021-08-05 18:13:11
【问题描述】:
我有一个包含 750,000 条记录的 InnoDB 表。它的主键是BIGINT。
当我这样做时:
SELECT COUNT(*) FROM table;
需要 900 毫秒。 explain 表示没有使用索引。
当我这样做时:
SELECT COUNT(*) FROM table WHERE pk >= 3000000;
需要 400 毫秒。 explain 表明在这种情况下使用了索引。
我希望在x >= pk >= y 的位置进行快速计数。
据我了解,由于我使用表的主键,因此我使用的是聚集索引,因此行(物理上?)由该索引排序。那么做这个计数不应该非常非常快吗?我原以为结果会在十几毫秒左右提供。
我已经读过,如果我只选择表格的一小部分,可以预期更快的结果。然而,我对做这些范围计数很感兴趣。也许我应该以不同的方式组织我的数据?
在另一种情况下,我有一个包含空间数据的表并使用 RTREE 索引,然后我使用 MBRContains 来计算匹配行(以及二级索引)。令人惊讶的是,这比上面的简单情况要快。
【问题讨论】:
-
您好用 COUNT(1) 代替 COUNT(*) 并在 pk 字段中使用聚集索引
-
经过的时间可能高度依赖于该表或索引是否被缓存的事实。您应该始终重复测量。此外,只有在实现索引快速全扫描访问方法时,计数才能从大范围的索引访问中受益,我不确定 InoDB 的情况
-
@RahulBiswas 这是个好主意。不过,MySQL 开发人员的想法相同,因此(对于 InnoDB),count(1) 和 count(*) 完全相同。
-
对于 InnoDB,数据存储在“主键”中。读取整个表和使用主键读取整个表是一回事。