Mysql - 查询 table 超过 10m 的数据
Mysql - query table with over 10m data
我正在维护一个使用 Java & mysql 的网络项目。
一个mysqltable有超过1000万条记录,我按日期对table进行了分区,以减少每个分区中的行数。也根据查询适当添加了索引
大部分查询只用到前1、2个分区,而且用到的分区记录总和不到200m,还是挺快的。
但是有些查询需要加载10个以上的分区来做一些statictis,因此单个查询涉及超过10m的记录,这很慢,并且随着数据的增长变得更糟。
table的一部分:
id(int), amount(double), type(varchar), user_id(int), event_date(timestamp)
-- `id` is primary key, `type` has index,
其中一个大查询类似于:
select count(id), sum(amount) group by (type)
where event_date between '2014-01-01' and '2014-12-31 23:59:59' and amount >= 10
-- The start & end datetime and the amount range might change.
我的问题是:
如何让超过10m条记录的查询更快?
这是我的猜测,但不确定:
- 使用mysql集群? (我以前从没用过。)
- 使用大缓存。 (Memcache,但是big query用的不多。)
您还可以执行其他几项操作来提高性能。
- 分析查询并根据需要引入索引。
- 识别应用程序的数据访问模式,您可以只缓存经常访问的数据以减少磁盘I/O。
如果旧数据是静态的,我会尝试做一些预聚合并将它们存储为表。然后根据预聚合表进行初始查询,一旦有人想要更多详细信息,然后转到数据的粒度级别。您可以创建许多不同的摘要/聚合表,即使您按 2-3 个字段进行分组(不知道您的数据 cotext/structures)。
但是请考虑一下...如果您有 1000 万条记录,并且您对所有静态/旧数据进行汇总数据,例如...3 个字段,这会将集合减少到甚至 100 万条记录,那帮助。然后,如果您只对其中一个条件的总计感兴趣,那么您可以按 3 个字段查询聚合,但按 1 个字段进行分组,因此您的 1m 条记录是查询的基础,而不是完整的 10 条记录。一旦用户找到fieldX=??? 交集的特殊需要和 fieldY=???, 然后转到您的 10m 记录集以获取可能需要的完整原始数据。
日期字段应用的是什么类型的分区?是范围型吗?如果您使用了错误的分区类型(如散列),那么它将查找几乎所有分区并导致分区无用。
我正在维护一个使用 Java & mysql 的网络项目。
一个mysqltable有超过1000万条记录,我按日期对table进行了分区,以减少每个分区中的行数。也根据查询适当添加了索引
大部分查询只用到前1、2个分区,而且用到的分区记录总和不到200m,还是挺快的。
但是有些查询需要加载10个以上的分区来做一些statictis,因此单个查询涉及超过10m的记录,这很慢,并且随着数据的增长变得更糟。
table的一部分:
id(int), amount(double), type(varchar), user_id(int), event_date(timestamp)
-- `id` is primary key, `type` has index,
其中一个大查询类似于:
select count(id), sum(amount) group by (type)
where event_date between '2014-01-01' and '2014-12-31 23:59:59' and amount >= 10
-- The start & end datetime and the amount range might change.
我的问题是:
如何让超过10m条记录的查询更快?
这是我的猜测,但不确定:
- 使用mysql集群? (我以前从没用过。)
- 使用大缓存。 (Memcache,但是big query用的不多。)
您还可以执行其他几项操作来提高性能。
- 分析查询并根据需要引入索引。
- 识别应用程序的数据访问模式,您可以只缓存经常访问的数据以减少磁盘I/O。
如果旧数据是静态的,我会尝试做一些预聚合并将它们存储为表。然后根据预聚合表进行初始查询,一旦有人想要更多详细信息,然后转到数据的粒度级别。您可以创建许多不同的摘要/聚合表,即使您按 2-3 个字段进行分组(不知道您的数据 cotext/structures)。
但是请考虑一下...如果您有 1000 万条记录,并且您对所有静态/旧数据进行汇总数据,例如...3 个字段,这会将集合减少到甚至 100 万条记录,那帮助。然后,如果您只对其中一个条件的总计感兴趣,那么您可以按 3 个字段查询聚合,但按 1 个字段进行分组,因此您的 1m 条记录是查询的基础,而不是完整的 10 条记录。一旦用户找到fieldX=??? 交集的特殊需要和 fieldY=???, 然后转到您的 10m 记录集以获取可能需要的完整原始数据。
日期字段应用的是什么类型的分区?是范围型吗?如果您使用了错误的分区类型(如散列),那么它将查找几乎所有分区并导致分区无用。