【问题标题】:Grouping by year and month with MySQL while leveraging indexes and avoiding temporary/filesort使用 MySQL 按年和月分组,同时利用索引并避免临时/文件排序
【发布时间】:2015-04-18 15:08:34
【问题描述】:

我有一个大型数据集(它将继续增长!),其中批量读取的数据存储在 DATE 列中,因为任何核心数据表中的所有行都属于特定日期(上下文是分析/报告)。

许多视图需要每月而不是每天详细级别的数据,我正在通过 SQL(SUM、AVG 等)根据需要聚合数据。

这也意味着我正在按YEAR()MONTH() 对数据进行分组,这不能使用DATE 列上的索引,并导致来自查询执行程序的Use temporaryUse filesort

DATE 列拆分为年、月和日的 3 个单独列是否是最佳解决方案?或者保留DATE 列(约束、排序等)并有一个“年月”(yyyymm)列也被索引?我不喜欢复制数据,但我只是不是 100% 知道这种情况下的最佳做法是什么。

【问题讨论】:

  • 最佳解决方案是什么?通常,最好的解决方案是存储日期,然后将其保留。
  • 仅仅因为使用临时和使用文件排序出现并不意味着您的查询将执行不佳。你有证据他们很慢吗?如果您正在寻找其他选项而不是 DATE 列,请考虑使用整数列并在其中存储基于纪元的数字时间戳

标签: mysql date query-optimization aggregate


【解决方案1】:

不要将 DATE 拆分为组成部分。困难大于假定的好处。

使用汇总表来避免冗长的分析/报告。请参阅my blog。粗略地说,每天晚上你都会计算过去一天的一些小计和计数,并将这些放在“汇总表”中。分析针对该表的运行速度要比针对“Fact”表的速度快得多。

对于 AVG,请务必存储 SUM() 和 COUNT(*),计算(在报告中)SUM(sums) / SUM(counts) as Average

【讨论】:

  • 如果需要汇总表实时汇总数据怎么办?意思是,原始数据表中有很多记录被不断插入,汇总表需要更新。维护和更新汇总表可能会成为瓶颈,对吧?在这种情况下,您会建议什么解决方案?
  • @tommyalvarez - 我的博客讨论了如何使用 IODKU 或“按需”保持最新状态。
【解决方案2】:

我认为在月份和日期列上使用GROUP-ing 和SELECT-ing 的最佳性能方法是在数据中添加MONTHYEAR 列。通过适当的索引使用获得的速度将超过一些更多/重复数据的痛苦。

请注意,MySQL 中有一个 YEAR 数据类型。

确保在monthyear 列上使用B-TREE 索引(而不是HASH)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-18
    • 2010-11-08
    • 2010-11-29
    • 1970-01-01
    • 1970-01-01
    • 2021-11-11
    相关资源
    最近更新 更多