2008-09-17 74 views
31

我有一个ETL过程,涉及大量使用SELECT INTO语句的存储过程(最少记录日志,因此速度更快,因为它们生成的日志流量较少)。在一个存储过程中发生的一批工作中,几个最昂贵的操作是看似只是缓存查询结果并将它们复制到正在创建的表中的急切假脱机。在SQL Server上避免急于假脱机操作的方法

关于eager spools的MSDN文档相当稀少。有没有人对这些是否真的有必要(以及在什么情况下)有更深入的了解?我有一些可能或可能不合理的理论,但是在查询中消除这些理论方面没有成功。

.sqlplan文件非常大(160kb),所以我猜这可能是不合理的,直接发布到论坛。

因此,这里有一些理论,可能是适合于具体的答案:

  • 查询使用一些UDF的数据转换,如解析格式的日期。这种数据转换是否需要在构建表之前使用eager spool来分配合理的类型(例如varchar长度)?
  • 作为上述问题的扩展,没有人有更深入的观点,看什么在查询中执行此操作或不执行此操作?

回答

24

我对假脱机的理解是,它对你的执行计划有点red her。是的,它会消耗大量的查询成本,但实际上它是SQL Server自动执行的一项优化,可以避免代价高昂的重新扫描。如果要避免假脱机,它所在的执行树的成本将会上升,几乎肯定整个查询的成本会增加。对于特别可能导致数据库的查询优化器如何解析执行,尤其是没有看到SQL代码的情况,我没有任何特别的了解,但是您最好相信它的行为。

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

在这种情况下,如果您尝试使用READ UNCOMMITTEDNOLOCK提示,则可能会消除某些线轴。 (显然,如果可能导致您处于不一致的状态,但您不希望这样做,但每个人的数据隔离要求都不相同)。 TOP运营商和OR运营商可以偶尔会导致假脱机,但我怀疑你正在做的ETL过程中的任何这些...

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

我会看到的最后一件事是,如果您正在进行可重新排序的任何连接,请尝试使用提示来强制连接顺序发生在您知道的最有选择性的顺序中。这有点远,但如果你已经坚持优化,尝试它并没有什么坏处。

+0

读取隔离可能适用于从源复制的暂存区进程的查询。另外,即使这不能解决我的特殊问题,它也增加了一些洞察力,因为在我的MSDN文献中没有提到有关急切假脱机操作的信息。 – ConcernedOfTunbridgeWells 2008-09-18 09:57:58