我處於一種奇怪的情況 - 我被要求優化依賴於延遲加載的搜索功能。我意識到速度的主要問題是由於分頁請求(大約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;
}
我最終使用這個答案緩存數據庫請求,這太棒了!不幸的是,事實證明,這個問題的大部分都來自其他地方,而且要優化更難:....-( –