我有一个有趣的delimma.我有一个非常昂贵的查询,涉及执行几个全表扫描和昂贵的连接,以及调用计算一些地理空间数据的标量UDF.
最终结果是包含呈现给用户的数据的结果集.但是,我无法返回我想在一次调用中显示用户的所有内容,因为我将原始结果集细分为页面并返回指定页面,我还需要获取原始整个数据集,并应用group by和join等来计算相关的汇总数据.
长话短说,为了将我需要的所有数据绑定到UI,这个昂贵的查询需要被调用大约5-6次.
所以,我开始考虑如何计算这个昂贵的查询一次,然后每个后续调用都可能以某种方式拉动缓存的结果集.
我想到了将查询抽象为一个存储过程的想法,该过程将CacheID(Guid)作为可空参数.
此sproc将使用cacheID将结果集插入缓存表,以唯一标识此特定结果集.
这允许需要处理此结果集的sprocs从前一个查询传入cacheID,它是一个简单的SELECT语句来检索数据(在cacheID上有一个WHERE子句).
然后,使用定期sql作业清除缓存表.
这非常有效,并且在零负载测试中真正加快了速度.但是,我担心这种技术可能会导致加载问题,对缓存表进行大量的读写操作.
所以,长话短说,我疯了吗?或者这是一个好主意.
显然我需要担心锁争用和索引碎片,但还有其他需要关注的问题吗?
解决方法
我之前已经这样做了,特别是当我没有足够的时间编辑应用程序时.我认为它有时是一种有效的方法,但通常在应用程序中有一个缓存/分布式缓存是首选,因为它可以更好地减少数据库的负载并更好地扩展.
天真的“只是在应用程序中执行”@R_301_463@案的棘手问题是,很多时候你有多个应用程序与数据库进行交互,如果你没有应用程序消息总线(或类似memcached),可以让你进行绑定每个应用程序有一个缓存可能很昂贵.
显然,对于您的问题,理想的@R_301_463@案是能够以更便宜的方式进行分页,而不需要通过所有数据来获取页面N.但有时它不可能.请记住,从数据库中流出的数据可能比将数据流从数据库流回到同一数据库中更便宜.您可以引入一个新服务,负责执行这些长查询,然后让您的主应用程序通过该服务与数据库通信.