代码之家  ›  专栏  ›  技术社区  ›  FlySwat

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

  •  8
  • FlySwat  · 技术社区  · 16 年前

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

    最终结果是一个resultset,它包含呈现给用户的数据。但是,我不能在一次调用中返回所有我想向用户显示的内容,因为我将原始resultset细分为多个页面,只返回指定的页面,而且我还需要获取原始的整个数据集,并应用group by和joins等来计算相关的聚合数据。

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

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

    我突然想到将查询抽象为一个存储过程,该存储过程接受一个CacheID(Guid)作为一个可空参数。

    此存储过程将使用cacheID将resultset插入缓存表,以唯一标识此特定resultset。

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

    然后,使用一个周期性的SQL作业,刷新缓存表。

    这工作得很好,而且在零负载测试中确实加快了速度。但是,我担心这种技术可能会在缓存表上造成大量读写的负载不足问题。

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

    显然,我需要担心锁争用和索引碎片,但还有什么需要关注的呢?

    2 回复  |  直到 16 年前
        1
  •  3
  •   Sam Saffron James Allen    16 年前

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

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

        2
  •  1
  •   Eric    16 年前

    你的tempdb在负载下会像气球一样膨胀,所以我会看的。将代价高昂的连接放在视图中并索引视图可能比为每个用户缓存表更容易。