在mysql中快速搜索不同的日期部分

时间:2012-04-24 12:14:19

标签: mysql database performance

我有一个包含约1000万个条目的数据库,每个条目都包含一个存储为DATE的日期。

我使用非唯一的BTREE索引该列。

我正在运行一个查询,计算每个不同年份的条目数:

SELECT DISTINCT(YEAR(awesome_date)) as year, COUNT(id) as count
FROM all_entries
WHERE awesome_date IS NOT NULL
GROUP BY YEAR(awesome_date)
ORDER BY year DESC;

此刻查询大约需要90秒,EXPLAIN输出显示原因:

id | select_type | table        | type  | possible_keys | key | key_len | ref | rows     | Extra
----------------------------------------------------------------------------------------------------------------------------------------
1  | SIMPLE      | all_entries  | ALL   | awesome_date  |     |         |     | 9759848  |  Using where; Using temporary; Using filesort

如果我FORCE KEY(awesome_date)将行数减少到约800万和key_len = 4,但仍然是Using where; Using temporary; Using filesort

我还会运行查询,选择DISTINCT(MONTH(awesome_date))DISTINCT(DAY(awesome_date)),并将相关的WHERE条件限制在特定年份或月份。

除了将年,月和日信息存储在单独的列中之外,有没有办法加快查询速度和/或避免临时表和文件输出?

1 个答案:

答案 0 :(得分:1)

如果不将日期拆分为3列,您可以:

  • 首先,你应该删除DISTINCT,这是没用的。 - ypercube 1分钟前编辑

  • 删除ORDER BY year,这有助于提高速度(一点点)。将Group By更改为:GROUP BY YEAR(awesome_date) DESC(仅适用于MySQL方言)。

  • COUNT(id)更改为COUNT(*)(假设id永远不会是NULL,这在许多MySQL版本中都会更快。)

    < / LI>

总之,查询将变为:

SELECT YEAR(awesome_date) AS year
     , COUNT(*) AS cnt              --- not good practise to use reserved words
                                    --- for aliases
FROM all_entries
WHERE awesome_date IS NOT NULL
GROUP BY YEAR(awesome_date) DESC ;

更好(更快)的解决方案是:

  • 您建议将列拆分为3(年,月,日)

  • 从MySQL更改为MariaDB(即MySQL分支),并使用VIRTUAL PERISTENT列作为年份,并在该虚拟列上添加索引。

  • 留在MySQL并自行添加一个持久的year列 - 使用触发器。