通过总和优化标题详细信息连接组

时间:2017-11-19 06:12:15

标签: sql join group-by sum mysql-5.7

我有两个表,分别是Activities和ActivityDetails,如下所示

create table Activities
(
    Id char(36) primary key,
    BranchId char(36) not null,
    ReferenceBranchId char(36) null,
    Date datetime not null,
    Type varchar(100) not null, -- Production, Delivery, Reception, SalesOrder
    Total decimal(16, 2) not null,
    Note varchar(400) null,
    IsActive bit(1) not null,
    CreatedById char(36) not null,
    CreatedDate datetime not null,
    ModifiedById char(36) null,
    ModifiedDate datetime null,
    constraint foreign key (BranchId) references Branches(Id) on delete cascade on update cascade,
    constraint foreign key (ReferenceBranchId) references Branches(Id) on delete cascade on update cascade,
    constraint foreign key (CreatedById) references Users(Id) on delete cascade on update cascade,
    constraint foreign key (ModifiedById) references Users(Id)
);

create table ActivityDetails
(
    Id char(36) primary key,
    ActivityId char(36) not null,
    No int not null,
    ItemId char(36) not null,
    Qty decimal(16,2) not null,
    IsActive bit(1) not null,
    CreatedById char(36) not null,
    CreatedDate datetime not null,
    ModifiedById char(36) null,
    ModifiedDate datetime null,
    constraint foreign key (ActivityId) references Activities(Id) on delete cascade on update cascade,
    constraint foreign key (ItemId) references Items(Id) on delete cascade on update cascade,
    constraint foreign key (CreatedById) references Users(Id) on delete cascade on update cascade,
    constraint foreign key (ModifiedById) references Users(Id)  
);

以及如下查询

select
    Activities.BranchId, Activities.Type, ActivityDetails.ItemId,
    sum(ActivityDetails.Qty)
from        Activities 
join        ActivityDetails
    on Activities.Id = ActivityDetails.ActivityId and ActivityDetails.IsActive = 1
where       Activities.IsActive = 1
group by    Activities.BranchId, Activities.Type, ActivityDetails.ItemId;

该查询导致工作台超时。

Error Code: 2013. Lost connection to MySQL server during query  600.495 sec

活动有~60.000行,ActivityDetails有~225.000行。

我已经尝试添加索引,但似乎没有效果。

alter table Activities add index BranchIdTypeIdx (BranchId, Type);
alter table ActivityDetails add index ItemIdQtyIdx (ItemId, Qty);

查询说明如下

 id | select_type | table            | partitions  | type | possible_keys | key        | key_len | ref           | rows    | filtered | Extra
 ---|-------------|------------------|-------------|------|---------------|------------|---------|---------------|---------|----------|---------------------------------------------
 1  | SIMPLE      | Activities       | null        | ALL  | PRIMARY       | null       |    null | null          |   58623 |    50.00 | Using where; Using temporary; Using filesort
 1  | SIMPLE      | ActivityDetails  | null        | ref  | ActivityId    | ActivityId |     108 | Activities.Id |       3 |    50.00 | Using where

如何优化查询(至少不会超时)?

1 个答案:

答案 0 :(得分:0)

我决定先缓存查询,然后每天在后台服务上运行它。唯一的缺点是如果缓存不是最新的,结果就不是实时的。

delete from ItemStatsOnProgress;
insert ItemStatsOnProgress
select
    Activities.BranchId,
    ActivityDetails.ItemId,
    sum(case when Type = 'Production' then ActivityDetails.Qty else 0 end),
    sum(case when Type = 'Delivery' then ActivityDetails.Qty else 0 end),
    sum(case when Type = 'Reception' then ActivityDetails.Qty else 0 end),
    sum(case when Type = 'SalesOrder' then ActivityDetails.Qty else 0 end)
from        Activities 
join        ActivityDetails
    on Activities.Id = ActivityDetails.ActivityId and ActivityDetails.IsActive = 1
where       Activities.IsActive = 1
group by    Activities.BranchId, ActivityDetails.ItemId;

delete from ItemStats;
insert ItemStats select * from ItemStatsOnProgress;