尝试从linq中的旧数据库编写此查询时,我遇到了性能问题。有没有更好的方法在linq中编写以下sql查询。
sql查询运行时间不到2秒,而当前的linq表达式需要6秒钟。
这是来自SQL 2008R2数据库。
这是sql查询
SELECT People.ID,
A.GameKey,
ClubCode,
case
WHEN ClubCode = Home_TM_CD then Visit_TM_CD
WHEN ClubCode = Visit_TM_CD then Home_TM_CD
end as Opponent,
count(case when (ClubCode <> PossessionTeam and STPlayType = 0) then 'super' end) as super_plays,
(SELECT count(PlayID)
FROM PLAY_LIST B
WHERE A.GameKey = B.GameKey
AND ClubCode <> PossessionTeam
AND PossessionTeam <> ''
AND STPlayType = 0
GROUP BY A.GameKey, A.ClubCode) as Total_Super_Play,
count(case when (ClubCode = PossessionTeam and STPlayType = 0) then 'plays' end) as plays,
(SELECT count(PlayID)
FROM PLAY_LIST B
WHERE A.GameKey = B.GameKey
AND ClubCode = PossessionTeam
AND STPlayType = 0
GROUP BY A.GameKey, A.ClubCode) as Total_Play,
Season,
Season_Type,
Week,
Game_DT
FROM PEOPLE
INNER JOIN PEOPLE_PARTICIPATION A ON People.ID = A.ID
inner join GAME on GameKey = gamekey
inner join PLAY_LIST on PLAY_LIST.GameKey = A.GameKey AND PLAY_LIST.PlayID = A.PlayID
WHERE Season = 2011
and People.ID = 1
group by People.ID,
Season,
Season_Type,
Week,
Game_DT,
A.GameKey,
ClubCode,
Home_TM_CD,
Visit_TM_CD
order by Season,
CASE WHEN Season_Type = 'Reg' THEN 1 ELSE 2 END, week, People.ID
这是我到目前为止的linq表达式
IQueryable<ProViewModel> playerList = (from people in db.PEOPLE
join participation in db.PARTICIPATION on people.ID equals participation.ID
join game in db.GAME on participation.GameKey equals game.Gamekey
join playlist in db.PLAY_LIST on new { gamekey = participation.GameKey, playID = participation.PlayID } equals new { gamekey = playlist.GameKey, playID = playlist.PlayID }
where people.ID == 1 &&
game.Season == 2011
group playlist by new PeopleParticipationGroup{
ID = people.ID,
SEASON = game.Season,
SEASON_TYPE = game.Season_Type,
WEEK = game.Week,
GAME_DT = game.Game_DT,
GameKey = participation.GameKey,
ClubCode = participation.ClubCode,
HOME_TM_CD = game.Home_TM_CD,
VISIT_TM_CD = game.Visit_TM_CD
} into groupedPeople
orderby groupedPeople.Key.SEASON
select new PeopleViewModel
{
ID = groupedPeople.Key.ID,
SEASON_TYPE = groupedPeople.Key.SEASON_TYPE,
WEEK = groupedPeople.Key.WEEK,
SEASON_TYPE_SORT =
(
groupedPeople.Key.SEASON_TYPE == "REG" ? 1 :
groupedPeople.Key.SEASON_TYPE == "POST" ? 2 : 3
),
GAME_DT = groupedPeople.Key.GAME_DT,
SEASON = groupedPeople.Key.SEASON,
GameKey = groupedPeople.Key.GameKey,
ClubCode = groupedPeople.Key.ClubCode,
Opponent =
(
groupedPeople.Key.ClubCode == groupedPeople.Key.HOME_TM_CD ? groupedPeople.Key.VISIT_TM_CD : groupedPeople.Key.HOME_TM_CD
),
HOME_TM_CD = groupedPeople.Key.HOME_TM_CD,
VISIT_TM_CD = groupedPeople.Key.VISIT_TM_CD,
PLAYS = (from t in groupedPeople
where t.PossessionTeam == groupedPeople.Key.ClubCode &&
t.STPlayType == 0
select t).Count(),
TOTAL_PLAYS = (from p in db.PLAY_LIST
where p.GameKey == groupedPeople.Key.GameKey &&
p.PossessionTeam == groupedPeople.Key.ClubCode &&
p.PossessionTeam != "" &&
p.STPlayType == 0
select p).Count(),
SUPER_PLAYS = (from t in groupedPeople
where t.PossessionTeam != groupedPeople.Key.ClubCode &&
t.STPlayType == 0
select t).Count(),
TOTAL_SUPER_PLAYS = (from p in db.PLAY_LIST
where p.GameKey == groupedPeople.Key.GameKey &&
p.PossessionTeam == groupedPeople.Key.ClubCode &&
p.PossessionTeam == "" &&
p.STPlayType == 0
select p).Count(),
}); ;
答案 0 :(得分:0)
我不完全确定如何编译查询,以及完成了多少优化。如果它按预期工作并按查询顺序将查询转换为linq函数调用,那么重新排列顺序可能有所帮助。
例如,您可以删除
where people.ID == 1 &&
game.Season == 2011
并将db.PEOPLE
替换为db.PEOPLE.where(p => p.id == 1)
,替换为db.GAME
。
这样可以避免加入后来被丢弃的结果。由于你有这些常数,所以可能值得将它们从分组中取出并直接进入选择。
另一方面,假设这是LINQ to SQL,那么上面的内容可能无济于事,您可以使用db.Log来查看SQL中查询的内容。然后,您可以重新排列,直到您的LINQ匹配或改进原始SQL。