2

让我从描述场景开始。我有一个使用SQL Server 2008的MVC 3应用程序。在其中一个页面中,我们显示从数据库返回的每个登录用户的UNIQUE列表。 用于返回产品列表的SQL查询(实际上是一个VIEW)非常昂贵。在内存或数据库中缓存昂贵的SQL查询?

  • 它基于非常复杂的业务需求,在现阶段无法改变。
  • 数据库架构无法更改或重新设计,因为它被其他应用程序使用。
  • 有50k产品和5k用户(每个用户可能有权访问1到50k产品)。

为了用于登录的用户显示该产品页面,我们使用:

SELECT TOP X * FROM [VIEW] WHERE UserID = @UserId -- where 'X' is the size of the page 

上述查询返回的最大的50行(最大页面大小)。 WHERE子句将行数限制为最大值50k(用户有权访问的产品)。 该页面需要大约5到7秒的时间才能加载,这正是上面SQL查询在SQL中运行的时间。 问题

用户到产品页面,并极有可能使用分页,重新排序结果,进入详细信息页面,等等,然后又回到了名单。每次需要5-7秒才能显示结果。

这是不可接受的,但同时业务团队已经接受,第一次加载产品页面可能需要5-7秒。因此,我们想到了CACHING

我们现在有两个选项可供选择,至少对我来说,最“显而易见”的是使用.Net缓存(在内存中/在proc中)。 (请注意,由于我们的提供商/托管合作伙伴的技术限制,目前不允许使用分布式缓存)。

但我对此不太舒服。我们最终会在内存中产生大量的产品(当有50或100个用户同时登录时),这可能会导致服务器上的其他问题,比如.Net不断删除缓存项目以释放​​空间,同时我们的代码插入新项目。

第二选项:

这里的主要问题是,它是非常昂贵的生成用户X产品X访问视图,所以我们认为我们可以创建一个平坦的桌面(或换句话说缓存所有产品x用户在数据库中)。该表格完全是该观点的结果。 但是,如果添加新产品,更改用户权限等,结果可能会随时发生变化。因此,我们需要不断刷新表格(可能需要几秒钟),这会变得有点复杂。同样,我们虽然可以实现某种缓存提供程序,并且根据用户的请求,我们将运行原始SQL查询并从视图中选择产品(5-7s,只能接受一次)并保存导致SQL中一个名为ProductUserAccessCache的平坦表。接下来的请求,我们会从这个缓存表中获取值(因为我们可以很容易地为那个特定用户确定缓存的结果),而不需要SQL中的计算。 每次添加产品或更改权限时,我们都会截断缓存表,并在新的请求时为请求的用户重新填充表。 对我来说这似乎不太复杂,但我们在这里所做的基本上是创建一个NEW缓存“提供者”。

  • 有没有人有这种问题的经验?
  • 使用.Net缓存(在proc中)会更好吗?
  • 有什么建议吗?
+1

您使用的是ORM吗? – pollirrata 2013-04-08 14:30:55

+0

实体框架4 – AndreCruz 2013-04-08 14:32:34

回答

1

我们在前段时间面临类似的问题,我们正在考虑使用EF缓存以避免延迟取回信息。我们的问题是1 - 2秒。延迟。 Here是一些可能有助于如何缓存扩展EF表的信息。高速缓存的一个缺点是您需要的信息有多新,所以您可以相应地设置高速缓存到期。根据截止日期的不同,用户可能需要等待以获取最新信息,但如果用户能够接受他们正在迁移的信息,以避免延迟,那么权衡是值得的。

在我们的场景中,我们决定更好地获得最新的信息,但如前所述,我们的等待时间并不长。

希望它有帮助

+0

我不知道这一个。它看起来非常强大,我会调查它。尽管我认为它不会涵盖我所有的需求,但从价格上看,值得一试.tx – AndreCruz 2013-04-08 14:57:01