【问题标题】:How to optimize mysql group by with DATE_FORMAT如何使用 DATE_FORMAT 优化 mysql 组
【发布时间】:2018-11-29 01:44:13
【问题描述】:

我有一个 sql。

select  count(id) as total, DATE_FORMAT(create_time,"%Y-%m-%d") as create_date
    from  table_name
    group by  DATE_FORMAT(create_time,"%Y-%m-%d");

然后定义列create_time。

`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP

据我所知,函数DATE_FORMAT不带索引,所以我的执行速度很慢。有什么办法可以优化吗?

mysql版本:5.6.34

【问题讨论】:

  • 我认为在 MySQL 中没有办法对此进行优化。我很好奇是否有人知道技巧。
  • @GordonLinoff 如果不能优化,那么这种情况下查询慢怎么解决?

标签: mysql sql database query-optimization sql-date-functions


【解决方案1】:

我会尝试使用 LEFT(create_time,10),它应该利用索引。

【讨论】:

    【解决方案2】:

    这不会加快速度,但更干净:

    select  count(*) as total,
            DATE(create_time) as create_date
        from  table_name
        group by  DATE(create_time);
    

    COUNT(id) 检查id 是否为NOT NULL;这可能是不必要的。

    INDEX(create_time) 将帮助一些,但它所做的只是将“表扫描”变成“索引扫描”。

    如果这是一个数据仓库应用程序(数以万计的一次性写入行、大量“报告”),那么我们可以讨论如何使这样的查询运行速度提高几个数量级。

    【讨论】:

    【解决方案3】:

    您可以创建生成的列并在该列上创建索引:

    ALTER TABLE table_name ADD COLUMN create_date DATE AS (DATE(create_time)) VIRTUAL;
    CREATE INDEX idx ON table_name(create_date);
    

    由于生成的列是虚拟的,它不会占用任何空间。 (但是,索引当然会使用额外的空间。)然后您可以在查询中使用这个生成的列:

    SELECT COUNT(*), create_date FROM t2 GROUP BY create_date;            
    

    【讨论】:

    • mysql5.6是否支持虚拟生成列?
    • 不,你需要 MySQL 5.7
    • 感谢您的建议,但是我无法升级mysql
    • 查询是否增加状态变量“Created_tmp_disk_tables”的值?如果是这样,增加 max_heap_table_size 和 tmp_table_size 的大小可能会有所帮助。
    • 这会提高查询速度吗?
    猜你喜欢
    • 1970-01-01
    • 2021-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-04
    • 1970-01-01
    • 2015-06-03
    相关资源
    最近更新 更多