2012-03-06 7 views
0

linqの従来のデータベースからこのクエリを書き込もうとすると、パフォーマンス上の問題が発生しています。 linqに以下のSQLクエリを書くためのよりよい方法がありますか?Linqバージョンの複数の結合とグループ化を伴うSQLクエリ

現在のlinq式は6秒以上かかるのに対し、sqlクエリは2秒未満で実行されます。

これはSQL 2008R2 DBのものです。ここで

は、ここで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

** UPDATE **パフォーマンスヒットは、2つの列「PLAYS」と「SUPERPLAYS」であるようです。私はそれらを定数値に設定しただけで、クエリはSQLクエリと同じレベルで実行されます。これらの列が追加されると、クエリは再び遅くなります – Matthew

答えて

0

です。それが期待どおりに動作し、それがlinq関数呼び出しに定義された順序でクエリを変換する場合は、順序を並べ替えると役に立ちます。例えば

、あなたは

where people.ID == 1 && 
game.Season == 2011 

を削除し、db.PEOPLE.where(p => p.id == 1)db.GAMEのための同様の交換にdb.PEOPLEを置き換えることができます。

これにより、後で破棄される結果を結合する作業が回避されます。あなたはこれらの定数を持っているので、それらをグループから取り出して選択肢にまっすぐ入れる価値があるかもしれません。

一方、これがLINQ to SQLであると仮定すると、おそらく上記は役に立ちません。db.Logを使用すると、SQLでクエリがどのように翻訳されているかを確認できます。その後、LINQが元のSQLと一致するか、または改善されるまで並べ替えることができます。

+0

私はEF 4.0を使用しているので、db.logはありません。私もあなたが提案したような場所を動かしてみましたが、違いはありませんでした。 – Matthew