存储过程需要4个小时才能运行

时间:2017-11-28 20:25:03

标签: sql-server

以下是我的存储过程。我正在进行一些基本的计算。以前它运行得更快,但现在突然间需要4个小时才能执行。我们的数据库大小为30GB。任何理由我需要这么长时间。我是否需要增加tempdb的大小?

我们在不同的服务器上运行相同的程序,该服务器的尺寸较小(5GB),只需要2分钟即可执行。

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[spWIPMatl]
WITH RECOMPILE
AS
    Declare @RKEY numeric(10,0)
    Declare @totMcost numeric(13,5)
    Declare @totsoldcost numeric (13,5)

    Declare @approved int
    Declare @nValue numeric(10,0)

    Declare c1 CURSOR FOR
        SELECT     
            DATA0006_1.RKEY, 
            SUM(DATA0095_1.QUANTITY * DATA0017_1.STD_COST) AS Material_cost, 
            SUM(0.35*DATA0095_1.QUANTITY ) AS Sold_cost
        FROM         
            DATA0095 AS DATA0095_1 
        INNER JOIN
            DATA0017 AS DATA0017_1 ON DATA0095_1.INVT_PTR = DATA0017_1.RKEY  
        INNER JOIN
            DATA0067 AS DATA0067_1 ON DATA0095_1.SRCE_PTR = DATA0067_1.RKEY 
        RIGHT OUTER JOIN
            DATA0006 AS DATA0006_1 ON DATA0067_1.WO_PTR = DATA0006_1.RKEY
        WHERE     
            (DATA0017_1.P_M = 'P') 
            AND (LEFT(data0017_1.INV_PART_NUMBER, 3) = '25-' 
                 OR LEFT(data0017_1.INV_PART_NUMBER, 3) = '85-') 
            AND (DATA0095_1.TRAN_TP = 13 or DATA0095_1.TRAN_TP = 14)
        GROUP BY 
            DATA0006_1.WORK_ORDER_NUMBER, DATA0006_1.ROOT_PTR, 
            DATA0006_1.RKEY, DATA0006_1.QUAN_SCH, DATA0006_1.QUAN_REJ, 
            DATA0017_1.INV_PART_NUMBER

        UNION ALL

SELECT     DATA0006_1.RKEY, SUM(DATA0095_1.QUANTITY * DATA0017_1.STD_COST) AS Material_cost, SUM(0.8*DATA0095_1.QUANTITY) AS Sold_cost
FROM         DATA0095 AS DATA0095_1 INNER JOIN
                      DATA0017 AS DATA0017_1 ON DATA0095_1.INVT_PTR = DATA0017_1.RKEY INNER JOIN
                      DATA0067 AS DATA0067_1 ON DATA0095_1.SRCE_PTR = DATA0067_1.RKEY RIGHT OUTER JOIN
                      DATA0006 AS DATA0006_1 ON DATA0067_1.WO_PTR = DATA0006_1.RKEY
/*WHERE     (DATA0017_1.P_M = 'P') and (LEFT(data0017_1.INV_PART_NUMBER, 3) ='35-' ) and DATA0095_1.tran_tp=13 */
WHERE     (DATA0017_1.P_M = 'P') and (LEFT(data0017_1.INV_PART_NUMBER, 3) ='35-' ) and (DATA0095_1.tran_tp=13 or DATA0095_1.TRAN_TP = 14)
GROUP BY DATA0006_1.WORK_ORDER_NUMBER, DATA0006_1.ROOT_PTR, DATA0006_1.RKEY, DATA0006_1.QUAN_SCH, DATA0006_1.QUAN_REJ , DATA0017_1.INV_PART_NUMBER

union all

SELECT     DATA0006_1.RKEY, SUM(DATA0095_1.QUANTITY * DATA0017_1.STD_COST) AS Material_cost, SUM(0*DATA0095_1.QUANTITY) AS Sold_cost

FROM         DATA0095 DATA0095_1 INNER JOIN
                      DATA0017 DATA0017_1 ON DATA0095_1.INVT_PTR = DATA0017_1.RKEY INNER JOIN
                      DATA0067 DATA0067_1 ON DATA0095_1.SRCE_PTR = DATA0067_1.RKEY RIGHT OUTER JOIN
                      DATA0006 DATA0006_1 ON DATA0067_1.WO_PTR = DATA0006_1.RKEY

/* WHERE  data0017_1.P_M ='P' and (LEFT(data0017_1.INV_PART_NUMBER, 3) <> '35-' and LEFT(data0017_1.INV_PART_NUMBER, 3) <> '85-' and LEFT(data0017_1.INV_PART_NUMBER, 3) <> '25-'  ) and DATA0095_1.tran_tp=13 */
WHERE data0017_1.P_M ='P' and (LEFT(data0017_1.INV_PART_NUMBER, 3) <> '35-' and LEFT(data0017_1.INV_PART_NUMBER, 3) <> '85-' and LEFT(data0017_1.INV_PART_NUMBER, 3) <> '25-'  ) and (DATA0095_1.tran_tp=13 or DATA0095_1.TRAN_TP = 14)
GROUP BY DATA0006_1.WORK_ORDER_NUMBER, DATA0006_1.ROOT_PTR, DATA0006_1.RKEY, DATA0006_1.QUAN_SCH, DATA0006_1.QUAN_REJ, DATA0017_1.INV_PART_NUMBER
ORDER BY 2, 1

OPEN c1
FETCH NEXT FROM c1
INTO @RKEY, @totMcost, @totsoldcost

WHILE @@FETCH_STATUS = 0
BEGIN

        /*SELECT @nValue = (SELECT RKEY FROM WIPStatusV3 WHERE RKEY=@RKEY)*/

        UPDATE tempWIPAeroV1 SET WIPmatl = WIPmatl + @totMcost, WIP_sold = WIP_sold + @totsoldcost WHERE RKEY=@RKEY


    FETCH NEXT FROM c1
    INTO @RKEY, @totMcost, @totsoldcost
END
delete from WIPAeroV1
insert into WIPAeroV1 select * from tempWIPAeroV1

CLOSE c1
DEALLOCATE c1`

2 个答案:

答案 0 :(得分:1)

很确定整个循环的东西可以沿着这些线重写。一些建议。你应该总是明确插入语句。指定insert语句中的列,并列出select语句中的列。使用ORDER BY时,应避免使用序号位置来支持使用列名。如果您的查询在某些时候发生变化,而您未按结果修改订单,则可能会出现意外顺序。

Response

答案 1 :(得分:0)

如果给出一大块查询,真的很难说。但有几点指示:

  1. 确保数据库中包含索引。通常在用于连接的列(外键)上,用于where子句中的比较。
  2. 避免在大型查询中使用游标,因为它们非常慢(https://www.sqlshack.com/sql-server-cursor-performance-problems/)。
  3. 那些表名,*畏缩*