性能不佳的查询需要帮助

Poorly performing query needs assistance

我有以下查询,它工作正常,但速度很慢,而且 return 结果速度不够快,无法满足我的需要。

它显示了 11 个位置中最常被选中的 9 名球员。

有没有人看到更好的写法?

select PlayerName, RankName, Position
from
(
select Opener1 as Player from Team
where CompetitionIDAuto = 1
union all
select Opener2 as Player from Team
where CompetitionIDAuto = 1
union all
select Bat1 as Player from Team
where CompetitionIDAuto = 1 
union all
select Bat2 as Player from Team
where CompetitionIDAuto = 1 
union all
select Bat3 as Player from Team
where CompetitionIDAuto = 1 
union all
select WK as Player from Team
where CompetitionIDAuto = 1 
union all
select AR1 as Player from Team
where CompetitionIDAuto = 1 
union all
select Bowl1 as Player from Team
where CompetitionIDAuto = 1 
union all
select Bowl2 as Player from Team
where CompetitionIDAuto = 1  
union all
select Bowl3 as Player from Team
where CompetitionIDAuto = 1 
union all
select Bowl4 as Player from Team
where CompetitionIDAuto = 1 
) a
Inner Join Player on a.Player = Player.PlayerIDAuto
Inner Join RankValue on Player.ODIRank = RankValue.RankIDAuto
Inner Join PlayerPosition on Player.ODIPosition = PlayerPosition.PlayerPositionIDAuto
group by PlayerName
order by count(*) desc
Limit 0,9

也许请尝试:

select PlayerName, RankName, Position
from
(
    select CONCAT('|', Opener1, '|', Opener2, '|', Bat1, '|', Bat2, '|', Bat3, '|', WK, '|', AR1, '|', Bowl1, '|', Bowl2, '|', Bowl3, '|', Bowl4, '|') as Player from Team
    where CompetitionIDAuto = 1 
) a
Inner Join Player on LOCATE(CONCAT('|', Player.PlayerIDAuto, '|'), a.Player) <> 0
Inner Join RankValue on Player.ODIRank = RankValue.RankIDAuto
Inner Join PlayerPosition on Player.ODIPosition = PlayerPosition.PlayerPositionIDAuto
group by PlayerName
order by count(*) desc
Limit 0,9

至于 table 的规范化(如果可能的话)我认为 @Tom 是对的。

如果我对你的问题的理解正确,最好的策略是将你的主要来源 table 一分为二,这样,而不是:

PlayerID_role1 PlayerID_role2 PlayerID_role3 ... CompetitionIDAuto

一个 table(团队)看起来像:

PlayerID RoleID CompetitionID

再加一个单独的 table(例如竞赛)来自动计算竞赛,其中将包括所有其他竞赛信息,例如

CompetitionIDAuto CompetitionName CompetitionDate...

然后你可以这样查询:

select PlayerName, RankName, Position from Team where CompetitionIdAuto = 1
Inner Join Player on Team.PlayerID = Player.PlayerIDAuto
Inner Join RankValue on Player.ODIRank = RankValue.RankIDAuto
Inner Join PlayerPosition on Player.ODIPosition = PlayerPosition.PlayerPositionIDAuto
group by Player.PlayerIDAuto
order by count(*) desc
Limit 0,9

注意:不要按 PlayerName 分组,因为 PlayerIDAuto(我猜)是一个自动递增的主索引字段,而 PlayerName 很可能根本不是索引。根据定义,按非索引字段分组很慢。 (您也可以对当前 table 的查询进行此改进)。