我有两个表,分别是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
如何优化查询(至少不会超时)?
答案 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;