【问题标题】:Inserting into temp table from view is very slow从视图插入临时表非常慢
【发布时间】:2013-09-05 13:02:12
【问题描述】:

我在查询中使用了不同的临时表。当我执行下面的查询时

 select * from myView 

执行只需 5 秒。

但是当我执行时

select * into #temp from myView 

需要 50 秒(是上述查询的 10 倍以上)。

我们从 SQL Server 2000 迁移到 SQL Server 2008 R2。在 SQL 2000 之前,这两个查询都需要相同的时间,但在 SQL Server 2008 中,执行时间要多 10 倍。

【问题讨论】:

  • 您如何衡量select * from myView 的结果?如果您正在寻找行首次出现的时间,那是错误的。您必须等到所有行都存在才能进行有效比较。
  • @Gordon Linoff 是的,当查询完成执行时,我正在检查执行结束时的执行时间。
  • 如果先定义临时表然后插入会发生什么,例如CREATE TABLE #Temp (...) INSERT #Temp (...) SELECT * FROM MyView。你能发布每个查询的执行计划吗?
  • @GarethD 我按照您的建议尝试了该方法,但它也需要与 select * int #temp from myview 相同的时间。
  • 还有执行计划?

标签: sql sql-server sql-server-2008 tsql temp-tables


【解决方案1】:

老问题,但是由于我遇到了类似的问题(尽管在 SQL Server 2014 上)并以我在任何现成资源上都没有看到的方式解决了它,我想我会分享它以希望它对其他人有所帮助.

我遇到了类似的情况:我创建的视图需要 21 秒才能返回其完整的结果集,但是当我将其转换为 SELECT..INTO 时需要 10 多分钟(此时我停止了查询) SELECT 是一个简单的,没有连接也没有谓词。我的预感是优化器正在根据附加的INTO 语句更改原始计划,该语句并没有像第一个实例那样简单地提取数据集,然后执行INSERT,而是以一种非常运行的方式改变它次优。

我首先尝试了OPENQUERY,试图强制先生成结果集,然后插入到临时表中。此方法的总运行时间为 23 秒,显然更接近原始的SELECT 时间。在此之后,我返回到我原来的 SELECT..INTO 查询并添加了一个 OPTION (FORCE ORDER) 提示以尝试复制 OPENQUERY 行为。这似乎成功了,时间与OPENQUERY 方法相当,23 秒。

我目前没有足够的时间来比较查询计划,但是如果您遇到此问题,作为一个快速而肮脏的选择,您可以尝试:

select * into #temp from myView option (force order);

【讨论】:

    【解决方案2】:

    在插入临时表之前,您的 select 语句中是否有 order by 子句,例如 select * from myView order by col1?如果有订单,则会大大减慢插入临时表的速度。如果是这种情况,请在插入发生时删除 order by 并在插入发生后 order by 像

    select * 
    into #temp
    from myView
    

    然后通过

    申请订单
     select * from #temp order by col1
    

    【讨论】:

      【解决方案3】:

      我认为,您的 tempdb 数据库有问题。可能是缓慢的 I/O、碎片、损坏的 RAID 等。

      【讨论】:

        【解决方案4】:

        是的,我会检查你的命令的执行计划。在排序或其他方面可能会有开销。

        【讨论】:

          猜你喜欢
          • 2013-04-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-04-02
          • 1970-01-01
          • 2012-08-19
          • 1970-01-01
          相关资源
          最近更新 更多