SQL Server存储过程需要很长时间才能执行

时间:2017-08-23 16:17:39

标签: sql-server stored-procedures

我还是SQL新手。我做了一个存储过程,里面有一些循环。我想在Delphi中创建一个包含少量参数的存储过程。

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[sp_operator6]
    @awal DATETIME,
    @akhir DATETIME,
    @pumpsMotor VARCHAR(500),
    @pumpsMobil VARCHAR(500),
    @pumpsSolar VARCHAR(500)
AS
BEGIN    
    DECLARE @tbl_pumpMotor TABLE (pumpnumber INT)

    INSERT INTO @tbl_pumpMotor 
        SELECT * 
        FROM dbo.SplitList(@pumpsMotor,',')

    DECLARE @tbl_pumpMobil TABLE (pumpnumber INT)

    INSERT INTO @tbl_pumpMobil 
        SELECT * 
        FROM dbo.SplitList(@pumpsMobil,',')

    DECLARE @tbl_pumpSolar TABLE (pumpnumber INT)

    INSERT INTO @tbl_pumpSolar 
        SELECT * 
        FROM dbo.SplitList(@pumpsSolar,',')

    DECLARE @var2 VARCHAR(50)
    DECLARE @tbl_result TABLE (Nama VARCHAR(MAX),
                               [shift 1 Motor] INT, 
                               [shift 2 Motor] INT, 
                               [shift 3 Motor] INT,
                               [shift 1 Mobil] INT, 
                               [shift 2 Mobil] INT, 
                               [shift 3 Mobil] INT,
                               [shift 1 Solar] INT, 
                               [shift 2 Solar] INT, 
                               [shift 3 Solar] INT)

    DECLARE @tbl_shift1 TABLE (shiftid INT)

    INSERT INTO @tbl_shift1 
        SELECT [id] 
        FROM [shift] 
        WHERE bizdate BETWEEN @awal AND @akhir 
          AND shiftworkdayid = 1

   declare @tbl_shift2 table (shiftid int)
insert into @tbl_shift2 select [id] from [shift] where bizdate between @awal and @akhir and shiftworkdayid=2

declare @tbl_shift3 table (shiftid int)
insert into @tbl_shift3 select [id] from [shift] where bizdate between @awal and @akhir and shiftworkdayid=3

declare hk_cursor cursor for
select distinct  operatorname from [transaction] where [date] between @awal and @akhir and OperatorName<>'RFID'

OPEN hk_cursor
fetch next from hk_cursor into @var2

while (@@fetch_status=0)
BEGIN
insert into @tbl_result
select operator.nama, 
shift1Motor.[shift 1 Motor], shift2Motor.[shift 2 Motor], shift3Motor.[shift 3 Motor],
shift1Mobil.[shift 1 Mobil], shift2Mobil.[shift 2 MoBIL], shift3Mobil.[shift 3 MoBIL],
shift1SOLAR.[shift 1 SOLAR], shift2SOLAR.[shift 2 SOLAR], shift3SOLAR.[shift 3 SOLAR]
from

  (select top 1 operatorname as Nama from [Transaction] where operatorname=@var2) as operator,
-- ====================================== MOTOR
  (SELECT count (distinct [ShiftId]) as [shift 1 Motor]  
  FROM [Transaction] 
  where 
  [date] between @awal and @akhir
  and operatorname = @var2
  and pumpnumber in ( select pumpnumber from @tbl_pumpMotor)
  and shiftid in (select shiftid from @tbl_shift1)
  )
  as shift1Motor,

(SELECT count (distinct 
      [ShiftId])
      as [shift 2 Motor]

  FROM [Transaction]
  where 
  [date] between @awal and @akhir
  and operatorname = @var2
  and pumpnumber in ( select pumpnumber from @tbl_pumpMotor)
  and shiftid in (select shiftid from @tbl_shift2)
 ) 
  as shift2Motor,

  (SELECT count (distinct [ShiftId])as [shift 3 Motor]
  FROM [Transaction]
  where 
  [date] between @awal and @akhir
  and operatorname = @var2
  and pumpnumber in ( select pumpnumber from @tbl_pumpMotor)
  and shiftid in (select shiftid from @tbl_shift3)
 ) 
  as shift3Motor,

-- ====================================== MOBIL

(SELECT count (distinct [ShiftId]) as [shift 1 MoBIL]
FROM [Transaction] 
  where 
  [date] between @awal and @akhir
  and operatorname = @var2
  and pumpnumber in ( select pumpnumber from @tbl_pumpMobil)
  and shiftid in (select shiftid from @tbl_shift1)
  )
as shift1Mobil,

(SELECT count (distinct [ShiftId])as [shift 2 MoBIL] 
FROM [Transaction]
  where 
  [date] between @awal and @akhir
  and operatorname =@var2
 and pumpnumber in ( select pumpnumber from @tbl_pumpMobil)
  and shiftid in (select shiftid from @tbl_shift2)
 ) 
  as shift2Mobil,

  (SELECT count (distinct [ShiftId])as [shift 3 MoBIL]
  FROM [Transaction] 
  where 
  [date] between @awal and @akhir
  and operatorname = @var2
  and pumpnumber in ( select pumpnumber from @tbl_pumpMobil)
  and shiftid in (select shiftid from @tbl_shift3)
 ) 
  as shift3Mobil,

  -- ====================================== SOLAR

  (SELECT count (distinct [ShiftId]) as [shift 1 SOLAR]   
 FROM [Transaction]
  where 
  [date] between @awal and @akhir
  and operatorname = @var2
  and pumpnumber in ( select pumpnumber from @tbl_pumpSolar)
  and shiftid in (select shiftid from @tbl_shift1)
  )
as shift1SOLAR,

(SELECT count (distinct [ShiftId]) as [shift 2 SOLAR]
  FROM [Transaction] 
  where 
  [date] between @awal and @akhir
  and operatorname = @var2
  and pumpnumber in ( select pumpnumber from @tbl_pumpSolar)
  and shiftid in (select shiftid from @tbl_shift2)
 ) 
  as shift2SOLAR,

  (SELECT count (distinct [ShiftId]) as [shift 3 SOLAR]
  FROM [Transaction] 
  where 
  [date] between @awal and @akhir
  and operatorname = @var2
  and pumpnumber in ( select pumpnumber from @tbl_pumpSolar)
  and shiftid in (select shiftid from @tbl_shift3)
 ) 
  as shift3SOLAR
FETCH NEXT from hk_cursor into @var2
END

close hk_cursor
deallocate hk_cursor

select * from @tbl_result
end

以及我如何执行

execute sp_operator6 '2015-8-10','2015-8-15','4,3,33,34,35,36','5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22','23,24,27,28,31,32'

在本地服务器上执行结果25记录花了7分钟。 有没有办法比这种方式更简单地编写这个存储过程? 非常感谢任何帮助。

提前致谢

1 个答案:

答案 0 :(得分:0)

首先,您需要开始考虑集合并避免循环,尤其是不需要的循环。

接下来你有一个巨大的交叉连接,这通常不利于性能。

如果这些表变量中有多个记录,则抛弃它们并使用临时表,然后将它们编入索引。

考虑将一个类型列添加到表变量(或临时表)中,并将所有信息放入一个表中。这可能会使用case语句进行聚合变得更加简单。数据透视查询也可能很有用。

您还需要查看执行计划,您可能会遗漏一些有用的索引。