我有一个表,其中的rank
列可以是1
,2
或3
。我需要计算每个排名的记录数,但我还需要显示所有按排名排序的数据。
从我的角度来看,实现这一目标的两种方法是:
用正常的方式拉出数据,
SELECT
然后运行第二次查询以获取计数:SELECT rank, COUNT(id) FROM tablename GROUP BY rank
- 使用普通的 SELECT 提取数据,然后在我得到的结果集上迭代两次:一次计算每个等级的出现次数,第二次实际显示数据。
哪种方式会更高效?它取决于桌子的大小吗?我想对于大表来说,这SELECT COUNT
会比计算(PHP、ASP.NET、Java)慢一点,特别是如果我要计算的离散值超过 3 个。
提高性能的推荐方法是:
a) 使用数据库完成繁重的计数、计算(在可能的情况下)
b) 减少访问数据库的次数和每次访问带回的数据量
鉴于此,我不确定您要将排名计数用于什么,但下面的查询将返回按排名排序的数据,但还包括一个“重复”列,其中包含每个排名的记录数
答案在很大程度上取决于数据的组织程度和查询本身。
例如,查看您在问题中的查询:
对于这个查询,我首先想到的是表是否被正确索引。
观察#1
如果 tablename 没有索引,则需要进行全表扫描。
观察#2
如果 tablename 在 rank 上有一个索引,你仍然会得到一个全表扫描,因为 MySQL 查询优化器排除了索引的使用,因为键分布和在一个完整的过程中必须为每个 rank 查找每个 id 的可能性等因素索引扫描。
观察#3
如果该表具有 (rank,id) 的复合索引,那么您可以进行全索引扫描。在大多数情况下,从不引用表的非索引列的全索引扫描会比全索引扫描快(参见观察#2)
观察#4
如果查询的写法略有不同
那么仅在 rank 列上的索引就足够了并产生完整的索引扫描。
结论
鉴于这些观察,向 MySQL 查询优化器展示两件事绝对是一件美事:
回想起来,预先给 MySQL 查询优化器尽可能多的优势也是一件好事。