2014-10-30 44 views
-1

我有一個代碼,我真的需要一些關於如何優化的建議。爲每個用戶獲得積分的SQL優化

我在系統中有超過10,000個用戶和1,000,000個代碼,所以這需要太長時間。

任何幫助表示讚賞:

List<User> userResults = (from u in myDB.Users 
        select new 
        { 
         User = u, 
         Sum = (from tc in myDB.TriviaCodes 
           where tc.userID == u.userID && 
           (tc.dateRedeemed.Value.Hour < 20 ? tc.dateRedeemed.Value.Date == date.Date : tc.dateRedeemed.Value.Date == yesterday.Date) 
           select tc).Sum(p => p == null ? 0 : p.pointsGained) 
        }) 
      .OrderByDescending(g => g.Sum) 
      .Where(g => g.Sum != 0) 
      .Select(g => g.User) 
      .Take(100) 
      .ToList(); 

這裏有兩個相關的表的SQL的:

CREATE TABLE [dbo].[TriviaCodes] (
    [TriviaCodeID]  INT   NOT NULL, 
    [codeNumber]  NVARCHAR (MAX) NULL, 
    [dateRedeemed]  DATETIME  NULL, 
    [answeredCorrectly] BIT   NULL, 
    [pointsGained]  INT   NULL, 
    [questionNumber] INT   NULL, 
    [userID]   INT   NULL, 
    [triviaPrizesCodes] INT   NULL, 
    PRIMARY KEY CLUSTERED ([TriviaCodeID] ASC) 
); 

CREATE TABLE [dbo].[Users] (
    [userID]  INT   NOT NULL, 
    [UDID]   NVARCHAR (MAX) NULL, 
    [firstName] NVARCHAR (MAX) NULL, 
    [lastName]  NVARCHAR (MAX) NULL, 
    [cellNo]  NVARCHAR (MAX) NULL, 
    [address]  NVARCHAR (MAX) NULL, 
    [city]   NVARCHAR (MAX) NULL, 
    [zip]   NVARCHAR (MAX) NULL, 
    [creditCode] NVARCHAR (MAX) NULL, 
    [GameThriveID] NVARCHAR (MAX) NULL, 
    [homeNumber] NVARCHAR (MAX) NULL, 
    PRIMARY KEY CLUSTERED ([userID] ASC) 
+3

這真的不是很有幫助。我們需要看到生成的實際T-SQL,最好是生成查詢計劃。 – 2014-10-30 13:05:19

+2

我不明白你所說的任何事情。 – 2014-10-30 13:07:25

+0

沒有Randy建議的額外細節,我們可以做很多幫助,除了可能建議將用戶總分保留在數據庫中而不是每次總結。 – DavidG 2014-10-30 13:10:06

回答

0

首先,你應該添加foregin關鍵用戶ID字段表TriviaCodes。 然後嘗試像這樣:

 var userResults = 
      (
       from u in myDB.Users 
       join tc in myDB.TriviaCodes on u.userID equals tc.userID 

       where 
        (tc.dateRedeemed.Value.Hour < 20 
         ? tc.dateRedeemed.Value.Date == date.Date 
         : tc.dateRedeemed.Value.Date == yesterday.Date) 
       select new 
       { 
        u, 
        tc 
       } 
      ) 


     .GroupBy(k => k.u.userID) 
       .Select(group => new 
       { 
        user = group.First().u, 
        points = group.Sum(p => p.tc.pointsGained) 
       }) 
     .OrderByDescending(u => u.points) 
     .Where(u => u.points > 0) 
     .Select(u => u) 
     .Take(100) 
     .ToList();