2017-08-23 197 views
-2

我还不熟悉SQL。我做了一个存储过程,里面有一些循环。我想在Delphi中用一些参数来创建一个存储过程。SQL Server存储过程需要很长时间才能执行

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 [email protected]) 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 [email protected] 
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' 

这需要7分钟,结果执行25只记录在本地服务器。 有什么办法可以比这种方式更简单地编写这个存储过程吗? 任何帮助非常感谢。

在此先感谢

+2

备注:您应该**不要**为存储过程使用'sp_'前缀。微软已经保留了这个前缀以供自己使用(参见*命名存储过程*)](http://msdn.microsoft.com/en-us/library/ms190669%28v=sql.105%29.aspx),以及你将来有可能冒着名字冲突的风险。 [这对你的存储过程性能也是不利的](http://www.sqlperformance.com/2012/10/t-sql-queries/sp_prefix)。最好只是简单地避免使用'sp_'并将其他内容用作前缀 - 或者根本没有前缀! –

+0

谢谢,会避免那个sp_。 –

+1

让我们从你的分配器开始。它是什么样子的?它有循环吗?你的程序代码是非常有问题的。它看起来像一个dotnet应用程序,而不是数据检索。尽可能避免循环和游标。然后你的主要查询是一堆单独的选择语句。整个过程需要彻底改革。它可以简化为一个没有循环和数十个查询的单个插入语句。我甚至会建议你的分隔列表可以成为表值参数并避免分裂。 –

回答

0

首先,你需要开始以成套思维,避免循环尤其是不必要的循环。

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

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

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

你还需要看看你的执行计划,你可能会错过一些有用的索引。

+0

谢谢HLGEM,正如你所说,我避免循环,所以我让程序内循环。它使查询更快。 –

相关问题