让我首先描述一下情况。我有一个使用Server 2008的MVC 3应用程序。在其中一个页面中,我们显示了从数据库返回的产品列表,并且在每个登录用户中都是唯一的。用于返回产品列表的SQL查询(实际上是一个视图)非常昂贵。
为了显示登录用户的“产品”页面,我们使用:
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。因此,我们考虑了缓存。
我们现在有两个选项可供选择,其中最“明显”的一种,至少对我来说,是使用.Net缓存(内存中/在proc中)。(请注意,由于技术上的限制,目前不允许与我们的提供商/托管伙伴进行分布式缓存)。
但我对此不太满意。我们可能会在内存中得到许多产品(当同时登录的用户有50或100个时),这可能会导致服务器上的其他问题,比如.Net不断地删除缓存项以释放空间,而我们的代码则插入新项。
第二个选项:
这里的主要问题是生成用户x products视图非常昂贵,因此我们认为可以创建一个平面表(换句话说,是数据库中所有产品x用户的缓存)。此表将完全是视图的结果。但是,如果添加了新产品、更改了用户权限等,结果随时都可能发生变化。因此,我们需要不断刷新表(可能需要几秒钟时间),这就开始变得有点复杂了。
类似地,我们可以实现某种缓存提供程序,并且根据用户的请求,我们将运行原始的SQL查询,并从视图(5-7,仅接受一次)中选择产品,并将结果保存为一个称为ProductUserAccessCache的平面表。下一个请求,我们将从这个缓存的表中获得值(因为我们可以很容易地识别结果是为那个特定的用户缓存的),使用一个不需要SQL计算的快速查询。在添加产品或更改权限时,我们将截断缓存的表,并在新请求时重新填充被请求的用户的表。对我来说,这似乎并不太复杂,但我们在这里所做的基本上是创建一个新的缓存“提供者”。
发布于 2013-04-08 14:47:32
不久前,我们面临着一个类似的问题,我们正在考虑使用EF缓存,以避免检索信息的延迟。我们的问题是1-2秒。延迟。这里是一些关于如何缓存扩展EF的表的信息。缓存的缺点之一是您需要的信息是多么新鲜,因此您相应地设置了缓存过期时间。根据过期时间,用户可能需要等待获得比他们想要的更多的新信息,但是如果您的用户可以接受他们为了避免延迟而看到过时的信息,那么这种权衡是值得的。
在我们的场景中,我们决定最好拥有新的信息,而不是快速,但正如我之前所说的,我们的等待时间并不长。
希望它能帮上忙
https://stackoverflow.com/questions/15881590
复制相似问题