2011-05-19 70 views
6

好吧,所以我一直在ASP.NET项目上工作了一段时间,似乎我做了一些糟糕的设计选择,回来困扰我作为项目数据包含的数据越来越大。在会话中缓存搜索结果vs保持大对象堆清洁

读完.NET内存管理之后,我想我已经确定了一整套潜在的原因。由于我正在做的事情并不特别,我想知道是否有一个标准模式来实现我想要做的事情,我失踪了。

所以我有一个(有点贵的查询),它产生1到20000结果之间的东西。在随后的请求中,我们可能只是对结果集进行分页,因此我将此结果存储在会话中。 Session是InProc。我想知道:

  • 是否有意义a)将结果b)存储在会话c)进程中?我想要(a)的速度。我不知道是否有比用户(b)更有效的方式存储它,并且如果我使用更复杂的状态服务器 - 是不是变得更慢(c)?或者这可能是解决方案,更快地处理这些大型对象,而不是将最后的结果集保留在RAM中,直到会话过期?

  • 如果任何结果集大约20000行最终可能会弄乱LOH,是否有一种通用的方法来解决这个问题?

我知道这个问题略有不足。我刚刚意识到我的总体设计可能存在缺陷(w.r.t.可扩展性),而我只是想估计一下究竟有多少缺陷。我希望可以收集一些有关标准模式的提示,但这些提示将会变成一个普遍有用的问题。

回答

1

为什么总是返回所有记录?我认为加快查询速度的最佳方法是只返回用户需要的数据..所以只有适合页面的数据!

尝试使用Google搜索ROW_NUMBER()(SQL Server)或LIMIT(mySQL)。

这里有两个产品教程

1)ScottGu's Blog

2)15 Second Tutorial

+0

谢谢。迄今为止,答案都非常有用,但这实际上非常适合手头的问题。我们已经开始使用Access后端。现在我们即将过渡到SQL Server,但是我认为如果应用程序的.NET部分无法处理内存负载,如果性能可能不会明显提高,那么在代价高昂的数据库迁移中毫无意义。然而,这可能是一个很好的观点,表明我们可以更好地优化.net部分,并在其背后有一个体面的数据库(假设经过短期的谷歌研究,这对于任意分类访问来说是不可能的)? – Nicolas78 2011-05-19 15:02:50

+0

实际上找到了一种方法在访问http://stackoverflow.com/questions/1900635/how-do-i-implement-pagination-in-sql-for-ms-access做分页,但鉴于解决方案的丑陋比较适当的SQL制定那里可能仍然是一个长期过期的迁移 – Nicolas78 2011-05-19 15:13:06

+0

您可以使用访问做的一件事是尝试使用以下一些SQL进行分页: SELECT TOP(10)FROM Table1 ORDER BY Id ...然后将最后一个ID存储在变量,然后你可以这样做: SELECT TOP(10)FROM Table1其中Id> * LastIdStored * .... 但最好的方法是迁移到其他数据库! – 2GDev 2011-05-19 15:39:43

1

不知道你的查询是什么,但为什么你会从数据库中拉出更多的行,而不是你需要同时显示你的用户?有了好的索引,拉起后续页面应该非常快速,然后只需要这样做,如果你需要这些页面。

另一种方法是只保存结果集的20000个项目的ID。这样,如果您需要翻阅它们,则可以通过主键快速提取单个行。

最后,也许你应该考虑使用Cache对象来存储结果而不是Session。这样你就可以让.NET决定何时处理对象,并且不会导致会话臃肿。

+0

感谢。我结束了标记2GDev的ROW_NUMBER()引用的答案,但你们基本上同意,现在我有一些重大的重建来临;) – Nicolas78 2011-05-20 08:31:10

1

您应该尽量避免将结果存储在会话中。如果用户在同一会话中使用多个浏览器选项卡(可能会发生),那么您的应用程序可能无法正常工作。

如果确实使用会话,肯定不要使用InProc模式,因为随着用户数量的增长,进程会吃掉内存并最终回收,即使超时还没有过去,用户的会话也会丢失。

尝试使用数据库进行页面切换,因为Keltex仅提及您要显示的数据。