请教关于mysql表数据过大如何优化日期查询的问题?

前提条件

假如我有一张list表有800万条数据,id是自增字段,time是无规律增长的时间戳,非索引

id...time
1...1688572800
2...1688745599
.........
8283122...1689026400
8283123...1689012634

现在我要查询time16885728001688745599之间的数据(示范中查询的时间戳是开头两行,实际运行过程中可能是几百万行数据中的某100行数据)

SELECT * FROM `list` WHERE `time` BETWEEN 1688572800 AND 1688745599;

问题

  • 每次查询要耗费4秒多,数据量还在不断增加
  • 想过添加time为索引,但是time是无规律的时间戳,设为索引就相当于有几百万条索引了

那么请问这种情况,要如何优化?还是说无解了。

阅读 3.4k
4 个回答
✓ 已被采纳

在这种情况下,可以考虑以下优化方法:

1添加一个分区列:你可以将表按照时间范围进行分区。例如,每个月或每个季度创建一个新的分区。这样可以减少查询的数据量,并提高查询性能。

2对时间字段进行哈希索引:尽管时间字段是无规律的时间戳,但你可以使用哈希函数来将时间戳转换为哈希值,并将该哈希值作为索引。这样可以减少索引的大小,提高查询性能。

3使用缓存:如果查询的时间范围不经常变化,你可以考虑将查询结果缓存起来,以减少后续查询的时间消耗。

4数据库分库分表:如果你的数据量非常大,你可以考虑将数据分散到多个数据库或多个表中,以减少查询的数据量。

5使用异步查询:如果查询的响应时间可以容忍延迟,你可以将查询操作转换为异步方式,以减少对主数据库的直接访问。

需要根据实际情况评估和实施这些优化方法,并根据系统的需求和资源来选择最适合的方案。

新手上路,请多包涵
  1. 首先建立索引肯定是可以的,查询肯定会变快很多很多,弊端是由于时间戳是无序的导致插入可能会变慢很多
  2. 如果此表后续数据量将突破亿级可以通过分库分表方式进行隔离,例如早于2023年的时间戳放到数据库一,其他数据放到数据库二,通过多节点来分散读写压力
  3. 如果不想在time列上建立索引,也可以把time和id的对应关系放入redis中,查范围就查出redis中的主键,再读库就很快了,弊端是程序若意外终止后启动对数据库有压力
  4. 理论的终极解决方案:直接放入内存数据库,代价是花费很高

首先索引占不了多少空间的,你可以设置完索引后,用工具看一下,没多少的正常操作。

添加索引:虽然time字段的值是没规律的,但是加索引可以提高查询速度,还有就是分区表根据time来划分

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏