加快 mysql SQL 查询,但数据集庞大

Posted

技术标签:

【中文标题】加快 mysql SQL 查询,但数据集庞大【英文标题】:Speed up mysql SQL query but with a huge dataset 【发布时间】:2020-01-08 15:04:48 【问题描述】:

我有一个超过 250 万行的表,我想运行以下 SQL 语句来获取

select count(*) 
  from workflow 
 where action_name= 'Workflow' 
   and release_date >= '2019-12-01 13:24:22' 
   and release_date <= '2019-12-31 13:24:22' 
   AND project_name= 'Web' 
 group 
    by page_id
     , headline
     , release_full_name
     , release_date

问题是它需要超过 2.7 秒才能按预期返回 0 行。有没有办法加快速度?我还有 6 个类似的 SQL 语句,因此至少需要 (2.7 秒 * 6) = 17 秒。

这是我的表架构

CREATE TABLE workflow (
 id int(11) NOT NULL AUTO_INCREMENT,
 action_name varchar(100) NOT NULL,
 project_name varchar(30) NOT NULL,
 page_id int(11) NOT NULL,
 headline varchar(200) NOT NULL,
 create_full_name varchar(200) NOT NULL,
 create_date datetime NOT NULL,
 change_full_name varchar(200) NOT NULL,
 change_date datetime NOT NULL,
 release_full_name varchar(200) NOT NULL,
 release_date datetime NOT NULL,
 reject_full_name varchar(200) NOT NULL,
 reject_date datetime NOT NULL,
 PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=2948271 DEFAULT CHARSET=latin1

我在这个查询中寻找的是获取上个月发布的页面数。具有 project_name = "web" 和 action_name = "Workflow"

【问题讨论】:

这些天来,我认为 250 万通常被认为是适度的。关于查询性能的问题总是至少需要所有相关表的 CREATE TABLE 语句,以及给定查询的 EXPLAIN 结果。 发布当前表架构和索引信息。另外,您是否获得了任何可以指示瓶颈所在位置的执行计划? 另外,请注意,这会返回每个(page_id、headline、release_full_name、start_date)的结果,但是无法知道哪个计数属于哪个结果,这似乎很奇怪。 我已经编辑了帖子以包含我正在使用的表格的结构。谢谢! 【参考方案1】:

这对 cme​​ts 来说有点大

    将 Group by 与 Count 函数一起使用没有任何意义。通常你需要在聚合之后计算数据库中的实际行数。不确定这是否是您的实际需求原因,因为 GROUP BY 会导致查询缓慢。

    在 (Web, start_date) 上使用复合索引作为列项目似乎具有最高的选择性。

其他信息,请分享解释计划。

【讨论】:

【参考方案2】:

假设您需要组的计数(您已列出),最好将组字段包含在 select(基本上)中

select page_id, headline, release_full_name, release_date, count(*) 
  from ...

添加带有 (page_id, heading) 的索引会优化得很好。

【讨论】:

以上是关于加快 mysql SQL 查询,但数据集庞大的主要内容,如果未能解决你的问题,请参考以下文章

在庞大的数据集上优化 Neo4j 密码查询

MySql查询具体某个时间段数据,结果集如何补全该时间段的所有记录并且标记为空值(时间显示除外)

在大型数据集上使用 JOIN 运行 SQL 查询

在庞大的数据集上使用 IN 是个好主意吗?

mysql-补充

记一次ES查询结果集失败