题解 | 计算总刷题数,并将所选列名改为总刷题数
计算总刷题数,并将所选列名改为总刷题数
https://www.nowcoder.com/practice/baf3fd3806994c0893eabea3d2750af6
select sum(pass_count) 总刷题数 from questions_pass_record_detail
豆老师拓展:
如何优化大量数据的聚合查询?
在处理大量数据的聚合查询时,可从索引优化、查询语句优化、数据库配置与架构优化 、数据预处理与缓存等方面进行优化,以下是具体的优化方法:
索引优化
- 创建合适的索引:如果查询中包含
WHERE
子句用于筛选数据,在相关列上创建索引能显著加快数据检索速度。例如在统计某个班级学生的平均成绩时,若WHERE
子句筛选班级列,就在班级列上创建索引。但要注意,索引并非越多越好,过多索引会增加数据插入、更新和删除的开销。 - 覆盖索引:尽量让索引覆盖查询中所需的列,这样数据库无需回表查询数据,能直接从索引中获取结果。比如查询只需要
id
和score
列进行聚合,创建包含这两列的复合索引,可提升查询性能。
查询语句优化
- 减少不必要的列:在
SELECT
子句中,只选择需要进行聚合计算的列,避免选择不必要的列。因为读取不必要的列会增加数据传输量和处理开销。例如只需要计算总销售额,那就只选择销售额列,而不选择商品描述等无关列。 - 合理使用
WHERE
子句:将过滤条件尽量前置,让数据库在读取数据时尽早过滤掉不需要的记录。同时,避免使用函数操作索引列,否则可能导致索引失效。比如,WHERE YEAR(create_time) = 2024
这种对索引列使用函数的方式应尽量避免,可改为WHERE create_time >= '2024-01-01' AND create_time < '2025-01-01'
。 - 优化
GROUP BY
操作:如果使用了GROUP BY
进行分组聚合,确保分组列上有适当的索引。并且,尽量减少分组的列数,分组列数越多,分组操作的开销越大。
数据库配置与架构优化
- 调整数据库参数:根据服务器的硬件资源(如内存、CPU 等),合理调整数据库的配置参数。例如,增加数据库的缓存大小,让更多的数据可以缓存在内存中,减少磁盘 I/O 操作。在 MySQL 中,可以调整
innodb_buffer_pool_size
参数来增大 InnoDB 存储引擎的缓冲池大小。 - 采用分区表:对于数据量非常大的表,可以根据某些条件(如时间、地域等)将表划分为多个分区。这样在进行聚合查询时,如果查询条件能命中分区,数据库只需扫描相关分区,而不是全表扫描。比如,按月份对订单表进行分区,查询某个月的订单聚合数据时,效率会大幅提升。
- 分布式数据库架构:当单机数据库无法满足性能需求时,可以考虑采用分布式数据库架构。将数据分散存储在多个节点上,通过并行计算来提高聚合查询的效率。像 ClickHouse 就是一款用于在线分析处理(OLAP)的列式数据库管理系统,非常适合处理大规模数据的聚合查询。
数据预处理与缓存
- 汇总表:对于一些经常需要进行聚合查询的数据,可以提前创建汇总表,定期更新汇总表的数据。在查询时直接从汇总表获取结果,减少实时聚合计算的开销。比如,每天晚上统计当天各个店铺的销售额并存储在汇总表中,白天查询时直接从汇总表读取。
- 使用缓存:将常用的聚合查询结果缓存起来,当下次查询相同数据时,直接从缓存中获取,无需再次执行查询。可以使用 Redis 等缓存工具来实现,例如将某个商品的月销量聚合结果缓存起来,在一定时间内重复查询时直接返回缓存值。