optimize header detail 按总和加入分组

optimize header detail join group by sum

我有两个表,分别是 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;

查询导致workbench超时。

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

我需要做什么来优化查询(至少不会超时)?

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

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;