MySql通过索引查询按顺序改进分组

MySql通过索引查询按顺序改进分组,mysql,sql,performance,indexing,Mysql,Sql,Performance,Indexing,我有一张这样的桌子: ╔════╦══════════════╦═══════════╗ ║ id ║ product ║ date ║ ╠════╬══════════════╬═══════════╣ ║ 1 ║ P1 ║ 2020-08-01║ ║ 2 ║ P2 ║ 2020-08-01║ ║ 3 ║ P2 ║ 2020-08-03║ ║ 4 ║ P3 ║ 2020-08-04║ ╚

我有一张这样的桌子:

╔════╦══════════════╦═══════════╗
║ id ║  product     ║ date      ║
╠════╬══════════════╬═══════════╣
║  1 ║ P1           ║ 2020-08-01║
║  2 ║ P2           ║ 2020-08-01║
║  3 ║ P2           ║ 2020-08-03║
║  4 ║ P3           ║ 2020-08-04║
╚════╩══════════════╩═══════════╝
目标是查询每天销售多少产品,因此查询为:

SELECT `date`, COUNT(id) AS `totalProductsSoldOnDate` 
FROM products 
GROUP BY `date` 
ORDER BY `date` ASC
输出为:

   date        totalProductsSoldOnDate
2020-08-01 |         2
2020-08-03 |         1
2020-08-04 |         1
嗯。现在让我们假设我们有一个场景,其中包含多条记录,并且该查询必须每天运行几次,我们现在需要关注性能,以便尽快检索结果

据我所知,在这种情况下,文献建议在GROUP BY和ORDER BY(本例为date)中涉及的列上放置一个索引

此时的问题是:这是正确的解决方案吗?

此外,假设放置索引很好:

  • 对于这种情况,哪一个是最有效的索引,为什么
  • 更重要的是:索引如何提高性能?即使有一个日期索引,我也需要扫描表上的所有行,否则我会遗漏什么
  • 将主键(日期、id)设置为InnoDB,并将表设置为InnoDB。这仍然需要进行完整的表扫描(因为您没有WHERE子句),但至少应该避免使用filesort

    如果您想更快,请创建一个包含所需输出的实体化视图,并使用product表上的触发器使其保持最新。然后,您将能够运行以下操作:

    SELECT * FROM mv_name ORDER BY date;
    
    将主键(日期、id)设置为InnoDB,并将表设置为InnoDB。这仍然需要进行完整的表扫描(因为您没有WHERE子句),但至少应该避免使用filesort

    如果您想更快,请创建一个包含所需输出的实体化视图,并使用product表上的触发器使其保持最新。然后,您将能够运行以下操作:

    SELECT * FROM mv_name ORDER BY date;
    
    使用辅助
    索引(日期,id)
    比使用as
    主键
    工作得更快。这是因为必须扫描的BTree较小

    要使任务显著加快,请总结当天晚上的数据:

    在这种情况下,让我们看看你有什么:

    WHERE -- not present
    GROUP BY -- just date
    ORDER BY -- matches the GROUP BY
    the whole query mentions only `date` and `id`
    
    让我们尝试建立一个最佳索引:

  • 处理
    中的
    ——无事可做。(可以继续)
  • 添加所有
    分组依据
    列:
    索引(日期,…)
    (确定以继续)
  • 由于排序依据匹配,因此无需执行任何操作。(可以继续)
  • 考虑制定一个“覆盖指数”。也就是说,在查询中的任何位置添加所需的所有其余列。(但不要使索引“太”大。)
    索引(日期,id)
  • 我所说的“同意继续”,是指没有一堵砖墙阻挡我们:

    • WHERE
    • 分组依据
      列表与
      冲突,其中
      (此处不是这种情况)
    • 订购依据
      缺少ASC和DESC,或不同意
      分组依据
    JOIN
    with中,提到
    中的多个表,其中
    (etc)是一堵砖墙。

    使用次
    索引(日期,id)
    比作为
    主键运行得更快。这是因为必须扫描的BTree较小

    要使任务显著加快,请总结当天晚上的数据:

    在这种情况下,让我们看看你有什么:

    WHERE -- not present
    GROUP BY -- just date
    ORDER BY -- matches the GROUP BY
    the whole query mentions only `date` and `id`
    
    让我们尝试建立一个最佳索引:

  • 处理
    中的
    ——无事可做。(可以继续)
  • 添加所有
    分组依据
    列:
    索引(日期,…)
    (确定以继续)
  • 由于排序依据
  • 匹配,因此无需执行任何操作。(可以继续)
  • 考虑制定一个“覆盖指数”。也就是说,在查询中的任何位置添加所需的所有其余列。(但不要使索引“太”大。)
    索引(日期,id)
  • 我所说的“同意继续”,是指没有一堵砖墙阻挡我们:

    • WHERE
    • 分组依据
      列表与
      冲突,其中
      (此处不是这种情况)
    • 订购依据
      缺少ASC和DESC,或不同意
      分组依据

    JOIN
    with中,提到
    中的多个表,其中
    (etc)是一堵砖墙。

    您真的要在所有日期运行此操作吗?通常像这样的报告只对特定的日期范围感兴趣。你真的要对所有日期运行它吗?通常,像这样的报告只对特定的日期范围感兴趣。在“id”之前加上“日期”有什么特别的原因吗?谢谢@战争法典360-我的答案增加了很多。您还有其他查询要分析吗?有很多微妙的问题没有包括在这个答案中。谢谢你详尽的回答!这个问题可以理解这些原则,但我知道关于这个话题还有很多。有什么特别的理由把“日期”放在“id”之前吗?谢谢@战争法典360-我的答案增加了很多。您还有其他查询要分析吗?有很多微妙的问题没有包括在这个答案中。谢谢你详尽的回答!这个问题可以理解这些原则,但我知道关于这个主题还有很多。谢谢。mv方法非常方便。谢谢。mv方法非常方便。