2016-06-28 140 views
1

我一直在研究一个运行缓慢的旧审计存储过程,我在应用索引和使查询变得更加可靠的方面取得了一些成功。SQL性能缓慢(改进插入临时表)

但是,存储过程仍然需要一分钟才能完成。我认为这个问题存在于临时表插入中。我曾尝试申请一个索引到临时表,但因为这只会降低性能:

索引表上的数字是 插入性能的最主要因素。表格具有的索引越多,执行变得越慢。插入语句是 无法直接受益于索引的唯一操作,因为它没有任何子句。

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 

执行计划: Execution_Plan

我认为瓶颈是#temp5表,我的问题是他们的一种方法,我可以加快插入到临时表或者是有一个更好的选择到临时表?

感谢您的帮助。

+0

请提供执行计划的链接,而不是图片 – TheGameiswar

+0

性能问题应包括'EXPLAIN ANALYSE'和一些关于表格大小,索引,当前时间表现,期望时间等的信息。'Slow'是一个相对术语,我们需要一个真正的价值来比较。 –

+0

执行计划显示将数据插入临时表占用总时间的41%。所以我认为它将大量的行插入到临时表中,但看起来最终结果只有3462行。任何人都可以解释吗?谢谢 – FLICKER

回答

3

我想可能有几个不同的问题原因。 至少,假设是由于一个记录中的大量字段会导致Temp Heap表中的页溢出。除此之外,tempdb中可能存在争用,甚至会出现缓慢。因此,一般建议可能是:
1.如已经建议的那样,尽量不要使用临时表。
2.如果可能,尝试限制记录大小以适合一页。或者甚至更好,如果你可以将2-3条记录放入一个页面。
3.如果可能,请使用带有聚簇索引的“分段”表,而不是临时表。不要截断该表,只执行删除。
4.如果使用临时表:在插入聚集索引之前创建表。
5.休闲保罗兰德尔的约TempDB的建议:http://www.sqlskills.com/blogs/paul/the-accidental-dba-day-27-of-30-troubleshooting-tempdb-contention/

对于较深的故障排除,我会建议,该查询的执行过程中,捕捉等待,锁,I/O,内存和CPU的活动。

+1

非常感谢您的帮助,在答案中使用了第4点我已经在15秒左右的时间内运行了存储过程。通过一些更多的调整,我相信我可以让它运行得更快。 –

+0

在第1点你建议不使用临时表,但是你会建议使用什么而不是临时表?我查看了表变量,CTE和派生表。然而,临时表被证明是更好的解决方案。 –

+0

见#3。一个“分期”表。这不是一颗银色子弹,但在某些特定情况下它可能会有所帮助。我真的不能说是否是你的情况。你最好知道你的争议在哪里,你可以试试。 –