【问题标题】:Caching expensive SQL query in memory or in the database?在内存或数据库中缓存昂贵的 SQL 查询?
【发布时间】:2013-04-08 14:20:30
【问题描述】:

让我从描述场景开始。我有一个带有 SQL Server 2008 的 MVC 3 应用程序。在其中一个页面中,我们显示了从数据库返回的产品列表,并且每个登录用户都是唯一的。 用于返回产品列表的 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-7s。

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

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

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

第二个选项:

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

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

  • 有人遇到过此类问题吗?
  • 使用 .Net 缓存(进程中)会更好吗?
  • 有什么建议吗?

【问题讨论】:

  • 你在使用 ORM 吗?

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


【解决方案1】:

我们前段时间遇到过类似的问题,我们正在考虑使用 EF 缓存来避免检索信息的延迟。我们的问题是 1 - 2 秒。延迟。 Here 是一些可能有助于如何缓存扩展 EF 的表的信息。缓存的缺点之一是您需要的信息有多新鲜,因此您需要相应地设置缓存过期时间。根据到期时间,用户可能需要等待更多时间才能获得最新信息,但如果您的用户可以接受他们可能会看到过时的信息以避免延迟,那么权衡是值得的。

在我们的场景中,我们决定获得最新信息比快速获得更好,但正如我之前所说,我们的等待时间并没有那么长。

希望对你有帮助

【讨论】:

  • 我不知道这个。它似乎非常强大,我将对其进行调查。快速浏览虽然我认为它不能满足我的所有需求,但值得尝试.tx
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-13
  • 1970-01-01
  • 2021-07-28
  • 2011-03-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多