SQL 性能缓慢(改进 Insert Into Temp Table)

SQL Performance Slow (Improve Insert Into Temp Table)

我一直在研究一个旧的审计存储过程,它 运行 很慢,我在应用索引和使查询更可搜索方面取得了一些成功。

但是存储过程仍然需要一分钟才能完成。我认为问题在于 temp table 插入。我确实尝试将索引应用于临时 table 但这只会降低性能,因为:

The number of indexes on a table is the most dominant factor for insert performance. The more indexes a table has, the slower the execution becomes. The insert statement is the only operation that cannot directly benefit from indexing because it has no where clause.

SQL代码

我已经在下面发布了处理时间最长的审计过程的代码片段,并包含了执行计划。

SELECT dbo.[Audit Result Entry Detail].PK_ID,
  dbo.[Audit Result Entry Detail]....... 
   45-50 other columns selected from Audit Result Entry Detail 
   (Note i need to select all these)
   dbo.[Audit Register].Audit_Date,
   dbo.[Audit Register].Audit_Type,
   dbo.[Audit Register].ContextUser
 INTO #temp5

 FROM dbo.[Audit Result Entry Detail]
   INNER 
    JOIN dbo.[Audit Register]
   ON dbo.[Audit Result Entry Detail].FK_RegisterID = dbo.[Audit Register].PK_ID
   INNER 
    JOIN (
     SELECT MAX(Audit_Date) AS DATE,
         FK_RegisterID
       FROM dbo.[Audit Result Entry Detail]
      INNER 
       JOIN dbo.[Audit Register]
      ON dbo.[Audit Result Entry Detail].FK_RegisterID = dbo.[Audit Register].PK_ID
   WHERE Audit_Date >= @StartDate AND Audit_Date < DATEADD(dd,1,@EndDate)
            --WHERE ((SELECT DATEADD(dd, 0, DATEDIFF(dd, 0, Audit_Date))) >= @StartDate 
             -- AND  (SELECT DATEADD(dd, 0, DATEDIFF(dd, 0, Audit_Date))) <= @EndDate)
              AND part_number = @ParticipantNumber
      GROUP 
         BY FK_RegisterID
   ) dt
   ON dbo.[Audit Result Entry Detail].FK_RegisterID = dt.FK_RegisterID
  AND dbo.[Audit Register].Audit_Date = dt.[date]
  WHERE part_number = @ParticipantNumber

执行计划:

我认为瓶颈是#temp5 table,我的问题是有什么方法可以加快插入临时文件的速度table 或者是否有更好的替代临时文件 table?

我想这个问题可能有几个不同的原因。 至少,假设是由于一条记录中的大量字段会导致临时堆中的页面溢出 table。除此之外,tempdb 中可能存在争用,甚至速度很慢。所以,一般的建议可能是:
1. 如前所述,尽量不要使用 temp table。
2. 如果可能,尽量限制记录大小以适合一页。或者更好,如果您可以将 2-3 条记录放入一页。
3. 如果可能的话,使用 "staging" table 和聚簇索引,而不是 temp table。不要截断 table,只做删除。
4. 如果使用 temp table:在插入之前创建 table,上面有聚簇索引。
5. Fallow Paul Randal 关于 TempDB 的建议:http://www.sqlskills.com/blogs/paul/the-accidental-dba-day-27-of-30-troubleshooting-tempdb-contention/

为了更深入的故障排除,我建议在执行该查询期间捕获等待、锁定、I/O、内存和 CPU activity。