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