在内存或数据库中缓存昂贵的SQL查询?

时间:2013-04-08 14:20:31

标签: asp.net-mvc-3 caching entity-framework-4 asp.net-caching database-caching

首先让我来描述一下这个场景。我有一个带有SQL Server 2008的MVC 3应用程序。在其中一个页面中,我们显示了从数据库返回的产品列表,每个登录用户都是UNIQUE。 用于返回产品列表的SQL查询(实际上是一个VIEW)非常昂贵。

  • 它基于非常复杂的业务需求,在此阶段无法更改。
  • 无法更改或重新设计数据库架构,因为其他应用程序使用它。
  • 有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

我们现在有两种选择可供选择,最明显的选择是#34;一个,至少对我来说,正在使用.Net缓存(在内存/进程中)。 (请注意,目前我们的提供商/托管合作伙伴不允许使用分布式缓存来解决技术问题。)

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

SECOND 选项:

这里的主要问题是生成User x Product x Access视图非常昂贵,所以我们认为我们可以创建一个平面表(或者换句话说,就是数据库中所有产品x用户的CACHE)。该表将完全是视图的结果。 但是,如果添加新产品,更改用户权限等,结果可能会随时更改。因此我们需要不断刷新表(这可能需要几秒钟),这开始变得有点复杂。

类似地,我们虽然可以实现某种缓存提供程序,但是根据用户的请求,我们将运行原始SQL查询并从视图中选择产品(5-7s,只接受一次)并保存该结果在SQL中称为ProductUserAccessCache的平面表中。下一个请求,我们将从这个缓存表中获取值(因为我们可以很容易地识别出为该特定用户缓存的结果),并且快速查询没有在SQL中进行计算。 无论何时添加产品或更改权限,我们都会截断缓存表,并在新请求时为所请求的用户重新填充表。 它对我来说似乎并不复杂,但我们在这里所做的基本上是创建一个新的缓存"提供商"。

  • 有没有人遇到过这种问题?
  • 使用.Net缓存(在proc中)会更好吗?
  • 有什么建议吗?

1 个答案:

答案 0 :(得分:1)

前一段时间我们遇到了类似的问题,我们考虑使用EF缓存,以避免检索信息的延迟。我们的问题是1 - 2秒。延迟。 Here是一些可能有助于如何缓存扩展EF的表的信息。缓存的一个缺点是您需要信息的新鲜程度,因此您可以相应地设置缓存过期时间。根据过期时间,用户可能需要等待获取超出他们想要的新信息,但如果您的用户可以接受他们为了避免延迟而发送过时的信息,那么权衡将是值得的。 / p>

在我们的场景中,我们决定更快地获取新信息,但正如我之前所说,我们的等待时间不长。

希望有所帮助