SQL CLR Web服务调用:限制开销

我正在尝试提高应用程序的查询性能,而且我在逻辑上陷入困境。

因此应用程序是专有的,因此我们无法改变应用程序端代码。 但是,我们已获得使用底层数据库的许可(令人惊讶的是)。 应用程序调用SQL Server数据库,因此我们运行的当前想法是创建一个与表名相同的视图并重命名基础表。 当应用程序访问视图时,视图会调用两个SQL CLR函数之一,这两个函数除了调用我们放在一起的Web服务之外什么都不做。 Web服务执行所有逻辑,并包含对外部专有API的API调用,该API执行一些额外的逻辑,然后返回结果。

这一切都有效,但是,在扩展到大型数据集(100,000多行)时,我们遇到了严重的性能问题。 非常清楚的一个原因是我们不得不一次使用Web服务在一行上工作,其中包括API调用,这会产生大量的延迟开销。

对此明显的解决方案是找出一种方法来限制每个查询必须命中Web服务的次数,但这就是我被困住的地方。 我已经阅读了有关这种潜在处理方案的几种不同方法,但作为一个总数据库新手,我很难掌握在这种情况下适合的情况。

如果有任何想法/建议,我会非常感激。

这里可能有几件事要看:

  1. 您的SQLCLR TVF是否将结果输出(即您是在添加一个集合,然后在最后返回该集合,还是在完成时释放每一行 – 要么yield return还是构建一个完整的枚举器)? 如果不是流式传输,那么你应该这样做,因为它允许立即消耗行而不是等待整个过程完成。

  2. 由于您要使用由TVF提供的视图替换表,因此自TVF以来,您自然会出现性能下降:

    • 不报告他们的实际行数。 T-SQL多语句TVF总是看起来返回1行,而SQLCLR TVF总是看起来返回1000行。
    • 不保持列统计信息。 从表中选择时,SQL Server将自动为WHEREJOIN条件中引用的列创建统计信息。

    由于这两件事,如果实际行数为100k,查询优化器将不会轻松生成适当的计划。

  3. 有多少SELECT等同时点击这个View? 由于View每次都访问相同的URI,因此受ServicePointManager( ServicePointManager.DefaultConnectionLimit )强加的并发连接限制的约束。 并且默认限制是高达2 ! 意思是,对该URI的所有其他请求,虽然已有2个活动/打开的HttpWebRequest ,但会耐心等待内联。 您可以通过设置HttpWebRequest对象的.ServicePoint.ConnectionLimit属性来增加此值。

  4. 基础数据的变化频率如何? 由于您切换到View,不带任何参数,因此您总是返回所有内容。 这打开了进行缓存的大门,有两个选项(至少):

    1. 缓存Web Service中的数据,如果尚未达到特定的时间限制,则返回缓存的数据,否则获取新数据,缓存并返回。
    2. 回到使用真正的表。 创建一个SQL Server代理作业,每隔几分钟(如果数据不经常更改,则可能更长):启动事务,删除当前数据,通过SQLCLR TVF重新填充,并提交事务。 这需要额外的SQL代理作业,但您可以回到更准确的统计数据!