在大型结果集上提高mysql中的分组性能

在大型结果集上提高mysql中的分组性能,mysql,indexing,group-by,query-performance,Mysql,Indexing,Group By,Query Performance,我们有一个很大的表,我们称之为数据,大约有20亿行,数据按日期、位置和名称进行索引。每行有一个“分数” 我们还有一个表,其中包含该表中所有不同的日期 如果我运行这样的查询: SELECT AVG(score) FROM Data d WHERE d.date IN ( SELECT today FROM dates dt WHERE dt.today > '2020-01-01'

我们有一个很大的表,我们称之为数据,大约有20亿行,数据按日期、位置和名称进行索引。每行有一个“分数”

我们还有一个表,其中包含该表中所有不同的日期

如果我运行这样的查询:

SELECT  AVG(score)
    FROM  Data d
    WHERE  d.date IN (
        SELECT  today
            FROM  dates dt
            WHERE  dt.today > '2020-01-01'
              AND  dt.today <  '2020-06-01'
              AND  d.location = 'Location1');
此查询将在几秒钟后返回。如果然后运行相同的查询,但查找按名称分组的平均分数,则查询需要几分钟。i、 e

SELECT  d.name, AVG(score)
    FROM  Data d
    WHERE  d.date IN (
        SELECT  today
            FROM  dates dt
            WHERE  dt.today > '2020-01-01'
              AND  dt.today <  '2020-06-01'
              AND  d.location = 'Location1')
            GROUP BY  .d.name;
不同名称的数量是几十万,有什么技术可以提高这样的查询速度吗?

首先试试这个

 CREATE INDEX data_name_score ON Data (location, date, name, score);
这个索引应该可以加速您的查询。对于您的尺寸表,创建它需要一些时间。也许通宵运行

为什么此索引会提高查询的性能?将索引视为索引所有列中所有值的排序列表

MySQL可以随机访问索引以查找第一个相关行。。。第一行,包含您选择的位置和您提到的范围内的日期

然后,它可以按顺序单步遍历索引,而根本不引用表来满足查询。姓名和分数在索引中

当它一步一步地通过索引时,瞧,索引项处于处理分组的理想顺序。它会遇到名称的所有分数值和值a,然后是b的所有分数,依此类推。不需要为每个不同的名称都指定一行的内部表

注意,如果您说的是MAXscore而不是AVGscore,那么您的查询可以通过一个所谓的。它们的速度几乎是奇迹般的快,甚至比您的查询使用的速度还要快

第二,像这样简化查询

SELECT d.name, AVG(score) avgscore 
  FROM Data d
 WHERE d.location = 'Location1'
   AND d.date >= '2020-01-01'
   AND d.date < '2020-06-01'
 GROUP BY d.name;
MySQL应该能够满足您的查询,并提供一个我建议的解决方案

而且,要注意,许多单列索引通常对性能有害,除非它们与您必须执行的实际查询相匹配。多个单列索引并不等同于多列索引

至于为什么没有索引时查询速度慢,您可以使用获取MySQL来准确地告诉您它是如何满足查询的。它可能需要检查表中的大部分千兆行,以筛选所需的行并生成结果

缺少右括号

使用连接日期…,而不是选择

1月1日是不是被故意遗漏了


请将您的问题包含在表格的CREATETABLE语句中,包括您拥有的索引和解释结果。。。查询您的查询。请阅读以下内容:然后请您的问题为我们提供更多信息。对于这样大小的表,了解索引是非常重要的。请注意,我并不是在试图提高第一个查询的速度,而是在试图理解为什么第二个查询需要如此多的时间。我认为这可能是因为它必须在磁盘上创建临时表,但不确定如何避免。对于像您这样大的表,您应该尽可能多地了解SQL索引。阅读Marcus Windand的优秀作品我知道添加该索引将改进初始查询,但它会改进分组依据吗?啊,因此,通过向索引添加“值”列,即使您从未按值分组,分组依据也不必访问表,只需访问索引。