我有一个遗留网站,由于性能不佳,需要进行一些优化。它是一个以linq-to-sql为数据层,MVP模式为UI模式的asp.net购物网站。
数据库中成本最高的实体是具有一对多关系的产品表和类别表。除非管理组的用户决定添加产品或类别,否则这两个实体可能不会定期更改。等等!所以如果我能有办法保持我的数据的活力…
首先,我想让我们使用AJAX进行数据检索,这样我只会创建那些需要查询或绑定的实体,但等等,如果不创建新的DataContext实例,我怎么能做到这一点?!!另一方面,由于内存成本的原因,对整个DataContext使用缓存被认为是一个糟糕的决定。那么,这里的最佳选择是什么呢?我该如何改进?
更新
1) 按照@HatSoft的建议去做。
缺点:这些方法不会帮助您的代码,只会帮助数据库。除此之外,可能还有内存问题,因为我们将数据放在内存中而不是渲染的html中,但是这可能是关于去耦合的最佳选择。
2) 使用输出缓存,我们在带有*.aspx通配符的http处理程序中有以下代码:
string pagePath = Context.Request.Url.AbsolutePath;
object cacheKey = application[pagePath];
if(cacheKey == null)
return; //application restarted/first run so cache the stuff
else
Context.Response.RemoveOutputCacheItem(pagePath);
缺点:现在我们应该将pagePath链接到页面使用的每个数据库实体,但如果我这样做,那么我将耦合事物,而不是去耦合它们。这种方法也会遇到一些硬编码。
3) 另一种解决方案是在后缓存模式下输出缓存,而不是控制缓存模式。使用Subsituation元素,并将OutPutCache持续时间设置为86400,这样页面将每24小时重新创建一次。
缺点:对用户控件进行硬编码,以动态生成Subsituation元素的html输出。
那么你有什么建议呢?
我建议您查看SqlDependency类,请阅读本文http://www.asp.net/web-forms/tutorials/data-access/caching-data/using-sql-cache-dependencies-cs
此外,如果适合您的应用程序,我建议您在应用程序启动时将数据加载到缓存中。请看这里的一个好例子http://www.asp.net/web-forms/tutorials/data-access/caching-data/caching-data-at-application-startup-cs
使用Linq2SQL,您可以使用LinqToCache,它为您的LINQ查询提供SqlDependency
支持的缓存。它将IQueryable<Products>
转换为IEnumerable<Products>
,并在第一次访问(底层IQueryable
的第一次迭代)后枚举形式内存。基于SqlDependency
数据更改通知,它将使列表无效,随后的访问将再次从DB中查询,并缓存结果。
我的建议是将"产品"列表和"类别"缓存在内存中,因为它们很少更改,而且我希望它们的大小相当有限。