2014-02-09 58 views
0

我處於一種奇怪的情況 - 我被要求優化依賴於延遲加載的搜索功能。我意識到速度的主要問題是由於分頁請求(大約1.5秒)和代碼之間的等待時間,我意識到控制器處理的每個頁面請求都會導致模型執行完整的數據庫查詢(而不是僅針對該頁面的結果的部分查詢)。在.NET MVC控制器請求中堅持一個變量

我們使用的是自定義的ORM,所以我不確定它在分頁方面如何處理(我認爲這就是爲什麼以這種方式實現的原因)。我們將數據庫結果存儲到IEnumerable中,然後使用LINQ進行篩選以檢索正確的頁面結果。

我想要做的就是將這個請求緩存在內存中 - 因爲我們把完整的結果放到一個IEnumerable中,將它放在某個地方會很方便(即使我必須將它傳遞到我的模型)。

有人建議在我的控制器或模型中使用靜態變量,但我認爲這會在多個請求中失敗。我在想,可能會有一種方法將其暫時存儲在服務器端的Session變量中,並在所有頁面請求完成後將其刪除。手動緩存,如果你願意。

我知道這不是最好的方式來做到這一點,但它可能是我在優化方面唯一的理智選擇(除非我們轉向不同的ORM)。有沒有人有任何建議,想法或批評?我將如何實現這樣的事情?

謝謝。

控制器代碼:

[HttpGet, JsonErrorCatcher, NoCache] 
    public ActionResult Accounts(int page = 0) 
    { 
     using (var context = PersistenceContext.Create()) 
     { 
      var model = new ContactsModel(context); 
      return new JsonNetResult(model.GetAccountsWebView(CurrentUser, page)); 
     } 
    } 

型號方法:

public ContactsWebViewModel GetAccountsWebView(User user, int page) 
    { 
     // This is what I'd like to avoid doing every time, by persisting this value. 
     // I can pass it into this method if necessary. 
     IEnumerable<Account> accounts = Context.Get<Account>() 
      .Include(x => x.AssignedGroups) 
      .Include(x => x.AssignedUsers) 
      .Include(x => x.Contacts) 
      .Where(x => x.IsActive) 
      .OrderBy(x => x.Name) 
      .ToArray(); 
     if (!user.HasPermission("Administrator.Contacts:View")) accounts = accounts.Where(x => x.IsReadableBy(user)); 
     int totalPages = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(accounts.Count())/25.0)); 
     accounts = accounts.Skip(page * 25).Take(25); 
     var model = GetWebView(user, null, accounts, page == 0); 
     model.TotalPages = totalPages; 
     return model; 
    } 

回答

1

如果你希望緩存中的數據是隻讀的並且同樣爲所有用戶,然後用static變量是一個非問題。

如果不是這種情況,那麼您應該將IEnumerable作爲CacheItem緩存在System.Runtime.Caching.MemoryCache對象中。您可以緩存多個版本以適應可能需要的各種場景。

更多關於MemoryCache on MSDN

+0

我最終使用這個答案緩存數據庫請求,這太棒了!不幸的是,事實證明,這個問題的大部分都來自其他地方,而且要優化更難:....-( –

2

最簡單的解決方案可能是使用內置的asp.net緩存。你不會說你使用的是什麼版本的框架,但是這樣的東西應該可以工作。

if (HttpContext.Cache["Key1"] == null) 
    HttpContext.Cache.Add("Key1", "Value 1", null, DateTime.Now.AddSeconds(60), 
     Cache.NoSlidingExpiration, CacheItemPriority.High, null); 

不管你喜歡,你都可以調整緩存時間。但請注意,如果結果很大,並且您擁有多個用戶,則可能會導致內存不足或導致大量的分頁延遲。

您可以使搜索條件成爲關鍵,只要結果相同總是以相同的搜索條件返回。

相關問題