sql-server - 避免 SQL Server 上急切的假脱机操作的方法

标签 sql-server tsql spool eager

我有一个 ETL 过程,其中涉及一个存储过程,该过程大量使用 SELECT INTO 语句(最少记录,因此速度更快,因为它们生成的日志流量较少)。在一个特定存储过程中发生的一批工作中,有几个最昂贵的操作是急切的假脱机,它们似乎只是缓冲查询结果,然后将它们复制到刚刚创建的表中。

关于 eager spools 的 MSDN 文档是相当稀疏的。有谁更深入地了解这些是否真的有必要(以及在什么情况下)?我有一些可能有意义也可能没有意义的理论,但没有成功地从查询中消除这些理论。

.sqlplan 文件非常大(160kb),因此我想将它们直接发布到论坛可能不合理。

因此,以下是一些可能适合特定答案的理论:

  • 查询使用一些 UDF 进行数据转换,例如解析格式化日期。此数据转换是否需要在构造表之前使用 eager spool 为表分配合理的类型(例如 varchar 长度)?
  • 作为上述问题的延伸,是否有人对查询中驱动此操作的因素有更深入的了解?

最佳答案

我对假脱机的理解是,它对你的执行计划来说有点转移注意力。是的,它占了查询成本的很大一部分,但它实际上是 SQL Server 自动进行的优化,以便避免昂贵的重新扫描。如果要避免假脱机,它所在的执行树的成本将会上升,并且几乎可以肯定整个查询的成本也会增加。我对什么可能导致数据库的查询优化器以这种方式解析执行没有任何特别的见解,特别是在没有看到 SQL 代码的情况下,但您最好相信它的行为。

但是,这并不意味着您的执行计划无法优化,具体取决于您的具体情况以及源数据的波动性。当您执行 SELECT INTO 时,您经常会在执行计划中看到假脱机项目,这可能与读隔离有关。如果适合您的特定情况,您可以尝试将事务隔离级别降低到成本较低的水平,和/或使用 NOLOCK 提示。我发现,在复杂的性能关键查询中,NOLOCK 如果安全且适合您的数据,可以极大地提高查询执行速度,即使似乎没有任何理由这样做。

在这种情况下,如果您尝试READ UNCOMMITTEDNOLOCK提示,您也许能够消除一些假脱机。 (显然,如果这样做可能会让您处于不一致的状态,那么您显然不想这样做,但每个人的数据隔离要求都不同)。 TOP 运算符和 OR 运算符有时会导致假脱机,但我怀疑您是否在 ETL 过程中执行这些操作...

您说得对,您的 UDF 也可能是罪魁祸首。如果您只使用每个 UDF 一次,那么尝试将它们内联起来以查看是否可以获得较大的性能优势将是一个有趣的实验。 (如果您找不到将它们与查询内联写入的方法,这可能就是它们导致假脱机的原因)。

我要考虑的最后一件事是,如果您正在执行任何可以重新排序的联接,请尝试使用提示来强制联接顺序按照您所知的最具选择性的顺序进行。虽然这个范围有点大,但如果您已经陷入优化困境,尝试一下也没什么坏处。

关于sql-server - 避免 SQL Server 上急切的假脱机操作的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/81278/

相关文章:

sql - 将表格分组为 15 分钟间隔

sql-server - 内存优化表 - INSERT 速度比 SSD 慢

SQL Server 2008 列前缀错误

hadoop - 水槽的 Spool Dir 可以在远程机器上吗?

sql - 将一列的多行转换为多列(即时)

sql - sql server存储过程中的多个表类型参数

sql - 查找没有匹配条件的记录

sql-server - 检查SQL Server中是否存在表

sqlplus 假脱机 : How to get rid of first, 空行?

file-upload - S3 假脱机桶/匿名 PUT