在SQLServer中使用缓存表,我疯了吗?

时间:2009-07-07 22:55:44

标签: sql-server caching

我有一个有趣的delimma。我有一个非常昂贵的查询,涉及执行几个全表扫描和昂贵的连接,以及调用计算一些地理空间数据的标量UDF。

最终结果是包含呈现给用户的数据的结果集。但是,我无法返回我想在一次调用中显示用户的所有内容,因为我将原始结果集细分为页面并返回指定页面,我还需要获取原始整个数据集,并应用group by和join等来计算相关的汇总数据。

长话短说,为了将我需要的所有数据绑定到UI,这个昂贵的查询需要调用5-6次。

所以,我开始考虑如何计算这个昂贵的查询一次,然后每个后续调用都可能以某种方式拉动缓存的结果集。

我想到了将查询抽象为一个存储过程的想法,该过程将CacheID(Guid)作为可以为空的参数。

此sproc会使用cacheID将结果集插入缓存表,以唯一标识此特定结果集。

这允许需要处理此结果集的sprocs从前一个查询传入cacheID,它是一个简单的SELECT语句来检索数据(在cacheID上有一个WHERE子句)。

然后,使用定期SQL作业,清除缓存表。

这很有效,并且在零负载测试方面确实加快了速度。但是,我担心这种技术可能会导致加载问题,对缓存表进行大量的读写操作。

所以,长话短说,我疯了吗?或者这是一个好主意。

显然我需要担心锁争用和索引碎片,还有其他需要关注的事情吗?

2 个答案:

答案 0 :(得分:3)

之前我已经这样做了,特别是当我没有足够的时间编辑应用程序时。我认为它有时是一种有效的方法,但通常在应用程序中有一个缓存/分布式缓存是首选,因此它可以更好地减少数据库的负载并更好地扩展。

天真的“只是在应用程序中执行”解决方案的棘手问题是,很多时候你有多个应用程序与数据库进行交互,如果你没有应用程序消息传递总线(或类似memcached),它可以让你进行绑定),因为每个应用程序有一个缓存可能很昂贵。

显然,对于你的问题,理想的解决方案是能够以更便宜的方式进行分页,而不需要通过所有数据来获取页面N.但有时它是不可能的。请记住,从数据库中流出的数据可能比将数据流从数据库流回到同一数据库中更便宜。您可以引入一个负责执行这些长查询的新服务,然后让您的主应用程序通过该服务与数据库通信。

答案 1 :(得分:1)

你的tempdb可能在负载下疯狂起来,所以我会注意到。将昂贵的连接放在视图中并索引视图可能比尝试为每个用户缓存表格更容易。