Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 尽管有索引,但使用GROUP BY查询的DISTINCT COUNT速度太慢_Mysql_Query Optimization - Fatal编程技术网

Mysql 尽管有索引,但使用GROUP BY查询的DISTINCT COUNT速度太慢

Mysql 尽管有索引,但使用GROUP BY查询的DISTINCT COUNT速度太慢,mysql,query-optimization,Mysql,Query Optimization,我有以下查询,统计每周每个区域的船只数量: SELECT zone, DATE_FORMAT(creation_date, '%Y%u') AS date, COUNT(DISTINCT vessel_imo) AS vessel_count FROM vessel_position WHERE zone IS NOT NULL AND creation_date >= DATE_SUB(CURDATE(), INTERVAL 12 MONTH) G

我有以下查询,统计每周每个区域的船只数量:

SELECT zone, 
    DATE_FORMAT(creation_date, '%Y%u') AS date, 
    COUNT(DISTINCT vessel_imo) AS vessel_count 
  FROM vessel_position
  WHERE zone IS NOT NULL
   AND creation_date >= DATE_SUB(CURDATE(), INTERVAL 12 MONTH)
  GROUP BY zone, date;
该表大约有4000万行。这方面的执行计划是:

+----+-------------+-----------------+------------+-------+--------------------+------+---------+------+----------+----------+------------------------------------------+
| id | select_type | table           | partitions | type  | possible_keys      | key  | key_len | ref  | rows     | filtered | Extra                                    |
+----+-------------+-----------------+------------+-------+--------------------+------+---------+------+----------+----------+------------------------------------------+
|  1 | SIMPLE      | vessel_position | NULL       | range | creation_date,zone | zone | 5       | NULL | 21190904 |    50.00 | Using where; Using index; Using filesort |
+----+-------------+-----------------+------------+-------+--------------------+------+---------+------+----------+----------+------------------------------------------+
列Vesser_imo、zone和creation_date均已编制索引。主键是复合键vessel_imo、creation_date

当我查看查询配置文件时,我可以看到我花了大量时间创建排序索引


我可以做些什么来进一步改进此查询吗?

这取决于筛选条件的选择性以及表结构。过滤条件是否选择了20%的行、5%、1%、0.1%

如果您的答案低于5%,则以下索引可能会有所帮助:

create index ix1_date_zone on vessel_position (creation_date, zone);
如果表中有许多和/或重列,则此选项可能仍然很慢,具体取决于筛选条件的选择性

否则,您可以尝试使用更昂贵的索引,以避免使用表,并执行以下操作:

create index ix2_date_zone_imo on vessel_position 
  (creation_date, zone, vessel_imo);
该索引的维护成本更高—读取、插入、更新和删除行—但对于您的select来说,它会更快


尝试这两个选项,并根据您的需要选择最佳选项。

SET@mystartdate=DATE\u subcontracate,间隔12个月

选择区域、日期\u格式创建\u日期、%Y%u'作为日期, 将不同的船舶作为船舶计数 从船舶位置 其中创建日期>=@mystartdate 和区域>0 按区域、日期分组

可能会在更短的时间内提供结果,请张贴您的每一个旧的和建议的第二次运行的比较时间

请发布新的解释选择…以确认创建日期索引现在已使用


除非允许更改旧数据,否则为什么必须收集12个月的历史记录,1个月以上的数据不会更改。

假设数据一旦插入,不会更改,然后构建并维护汇总表

该表将有三列:区域、周和该周的计数。在每周开始时,仅为前一周的行构建一个分区;跳过空值。然后构建一个针对该表的查询-它将非常快,因为它将获取更少的行


同时,INDEXcreation\u date,zone,Vesser\u imo作为二级索引,将使每周任务的效率相当于当前查询的52倍。

2100万行中的大多数都超过一年了吗?@RolandStarke No,每个月都有大量数据。大约一百万。Mh,没有线索,也许你可以尝试将组更改为“截止日期”,区域,因为行可能是按日期排序的,而不是区域,但我认为这不会有多大作用。请发布一个显示创建表Vesser_position和B显示Vesser_position索引的文本结果,以便进行分析。这个查询运行了多长时间?您知道第一行将是一个不完全的星期,因此计数可能会有点低吗?