【问题标题】:SQL CLR Web Service Call: Limiting OverheadSQL CLR Web 服务调用:限制开销
【发布时间】:2016-06-14 04:04:56
【问题描述】:

我正在尝试提高应用程序的查询性能,但我在逻辑上卡住了。

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

这一切都有效,但是,在扩展到大型数据集(100,000+ 行)时,我们遇到了严重的性能问题。很明显的原因是我们不得不一次处理一行的 Web 服务,其中包括 API 调用,这会产生大量的延迟开销。

对此的明显解决方案是找出一种方法来限制每次查询必须命中 Web 服务的次数,但这就是我遇到的问题。我已经阅读了一些可能处理此类场景的不同方法,但作为一个数据库新手,我很难掌握在这种情况下什么是合适的。

如果有任何想法/建议,我将不胜感激。

【问题讨论】:

  • 调用 Web 服务没有什么“更多”——没有什么比调用外部进程更重要了,更不用说远程进程了。如果要导入 100K 行,从其他系统导出它们,然后将它们导入数据库。如果找不到更好的方法从其他系统批量导出它们,请编写一个程序定期刷新数据,可能并行执行多个请求

标签: c# sql-server performance web-services sqlclr


【解决方案1】:

这里可能有几件事要看:

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

  2. 由于您将 Table 替换为源自 TVF 的 View,因此您自然会遇到 TVF 后的性能下降:

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


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

  3. 有多少SELECTs 等同时访问此视图?由于 View 每次都访问相同的 URI,因此您受到 ServicePointManager (ServicePointManager.DefaultConnectionLimit) 施加的并发连接限制的约束。默认限制是惊人的2!这意味着,对该 URI 的所有其他请求,虽然已经有 2 个活动/打开的HttpWebRequests,但将耐心地等待内联。您可以通过设置HttpWebRequest 对象的.ServicePoint.ConnectionLimit 属性来增加此值。

  4. 基础数据多久更改一次?由于您切换到视图,它不带任何参数,因此您总是返回所有内容。这为做一些缓存打开了大门,有两种选择(至少):

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

有关使用 SQLCLR 的更多信息,请访问:SQLCLR Info

【讨论】:

    猜你喜欢
    • 2015-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-29
    相关资源
    最近更新 更多