性能不佳的查询需要帮助

时间:2015-01-05 00:23:40

标签: mysql

我有以下查询可以正常工作,但速度非常慢,并且不能足够快地返回结果以满足我的需求。

它显示了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

2 个答案:

答案 0 :(得分:0)

请尝试:

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

关于你桌子的规范化(如果可能的话)我认为@Tom是对的。

答案 1 :(得分:0)

如果我正确理解您的问题,最好的策略是将主要源表分成两部分,以便代替:

PlayerID_role1 PlayerID_role2 PlayerID_role3 ... CompetitionIDAuto

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

PlayerID RoleID CompetitionID
再加上一个单独的表格(例如竞赛)来自动计算比赛,其中包括所有其他比赛信息,例如

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很可能根本不是索引。根据定义,按非索引字段分组的速度很慢。 (您也可以对当前表上的查询进行此改进)。