Sql 执行存储过程花费的时间太长

Sql 执行存储过程花费的时间太长,sql,Sql,每当我进行购买或销售时,我都试图更新所有库存物品的现存量。我有一个存储过程来完成这项工作。它运行得很好,但当我有2000个库存项目时,执行查询需要45分钟以上——有什么想法吗 CREATE PROCEDURE [dbo].[UpdateProducts] AS BEGIN DECLARE @LoopCounter INT , @MaxCode INT, SELECT @LoopCounter = MIN(ProductId), @MaxCode = MAX(ProductId

每当我进行购买或销售时,我都试图更新所有库存物品的现存量。我有一个存储过程来完成这项工作。它运行得很好,但当我有2000个库存项目时,执行查询需要45分钟以上——有什么想法吗

CREATE PROCEDURE [dbo].[UpdateProducts]
AS
BEGIN
    DECLARE @LoopCounter INT , @MaxCode INT, 

    SELECT @LoopCounter = MIN(ProductId), @MaxCode = MAX(ProductId) 
    FROM products

    WHILE (@LoopCounter IS NOT NULL
           AND @LoopCounter <= @MaxCode)
    BEGIN
        UPDATE Products 
        SET QuantityOnHand  = (SELECT 
                                   ((SELECT ISNULL(SUM(ISNULL(Qty, 0)), 0) 
                                     FROM BILLDETAILS 
                                     WHERE Pid = @LoopCounter) -
                                    (SELECT ISNULL(SUM(ISNULL(Qty, 0)), 0) 
                                     FROM InvoiceDetails 
                                     WHERE Pid = @LoopCounter) -
                                    (SELECT ISNULL(SUM(ISNULL(Qty, 0)), 0) 
                                     FROM SalesDetails 
                                     WHERE Pid = @LoopCounter))
        WHERE ProductId= @LoopCounter

        SELECT @LoopCounter = MIN(ProductId) 
        FROM Products
        WHERE ProductId > @LoopCounter
    END  
END
CREATE过程[dbo]。[UpdateProducts]
作为
开始
声明@LoopCounter INT、@MaxCode INT、,
选择@LoopCounter=MIN(ProductId),@MaxCode=MAX(ProductId)
来自产品
WHILE(@LoopCounter不为空
和@LoopCounter@LoopCounter
结束
结束

我不明白您为什么要在
循环时使用
来实现这一点。您应该可以通过使用
加入
轻松更新所有产品:

UPDATE p
SET p.QuantityOnHand =
    (ISNULL(SUM(ISNULL(b.Qty, 0)), 0) -
     ISNULL(SUM(ISNULL(i.Qty, 0)), 0) -
     ISNULL(SUM(ISNULL(s.Qty, 0)), 0))
FROM Products p
INNER JOIN BillDetails b ON p.ProductId = b.Pid
INNER JOIN InvoiceDetails i ON p.ProductId = i.Pid
INNER JOIN SalesDetails s ON p.ProductId = s.Pid

我不明白您为什么要使用
WHILE
循环来实现这一点。您应该可以通过使用
加入
轻松更新所有产品:

UPDATE p
SET p.QuantityOnHand =
    (ISNULL(SUM(ISNULL(b.Qty, 0)), 0) -
     ISNULL(SUM(ISNULL(i.Qty, 0)), 0) -
     ISNULL(SUM(ISNULL(s.Qty, 0)), 0))
FROM Products p
INNER JOIN BillDetails b ON p.ProductId = b.Pid
INNER JOIN InvoiceDetails i ON p.ProductId = i.Pid
INNER JOIN SalesDetails s ON p.ProductId = s.Pid
试试这个

create PROCEDURE [dbo].[UpdateProducts]
as 
 DECLARE @productIdCursor AS int

 DECLARE
   countProduct 
 CURSOR FOR
  SELECT productId FROM Products

 OPEN   countProduct
  FETCH NEXT FROM countProduct INTO @productIdCursor
 WHILE @@fetch_status = 0
BEGIN

declare @value decimal(18,2)

set @value=(select      
    (select  ISNULL (SUM (isnull (Qty,0)),0) from BILLDETAILS where Pid = @productIdCursor)          -
    (select  ISNULL (SUM (isnull (Qty,0)),0) from InvoiceDetails where Pid = @productIdCursor)       -
    (select ISNULL (SUM (isnull (Qty,0)),0) from  SalesDetails where Pid = @productIdCursor)
    from Products where ProductId= @productIdCursor)

   update Products 
   set QuantityOnHand  =@value
   where ProductId= @productIdCursor

   print @value
    print @productIdCursor
     FETCH NEXT FROM countProduct INTO @productIdCursor

END

CLOSE countProduct
DEALLOCATE countProduct
如果需要,只需更改varieble“@value”的类型

create PROCEDURE [dbo].[UpdateProducts]
as 
 DECLARE @productIdCursor AS int

 DECLARE
   countProduct 
 CURSOR FOR
  SELECT productId FROM Products

 OPEN   countProduct
  FETCH NEXT FROM countProduct INTO @productIdCursor
 WHILE @@fetch_status = 0
BEGIN

declare @value decimal(18,2)

set @value=(select      
    (select  ISNULL (SUM (isnull (Qty,0)),0) from BILLDETAILS where Pid = @productIdCursor)          -
    (select  ISNULL (SUM (isnull (Qty,0)),0) from InvoiceDetails where Pid = @productIdCursor)       -
    (select ISNULL (SUM (isnull (Qty,0)),0) from  SalesDetails where Pid = @productIdCursor)
    from Products where ProductId= @productIdCursor)

   update Products 
   set QuantityOnHand  =@value
   where ProductId= @productIdCursor

   print @value
    print @productIdCursor
     FETCH NEXT FROM countProduct INTO @productIdCursor

END

CLOSE countProduct
DEALLOCATE countProduct

只需更改变量“@value”的类型如果您需要

我找出了我的查询速度慢的原因,我有一个列存储每行的上次更新日期和时间。我使用触发器更新了该列,这大大影响了性能。

我找出了我的查询速度慢的原因,我有一个列存储每行的上次更新日期和时间。我被更新了通过使用触发器删除该列,会显著影响性能。

为什么是SP?只需进行更新。1)您使用的是什么RDBMS?2) 您应该尝试使用
游标
,因为您实现循环的方式根本没有效率。您正在迭代表中的每一行。随着表变大,此查询的性能将恶化。有两种选择:按照@diiN\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。通过购买或出售。为什么是SP?只需进行更新。1)您正在使用什么RDBMS?2) 您应该尝试使用
游标
,因为您实现循环的方式根本没有效率。您正在迭代表中的每一行。随着表变大,此查询的性能将恶化。有两种选择:按照@diiN\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。通过购买或销售。我得到以下错误:聚合可能不会出现在UPDATE语句的集合列表中。我得到以下错误:聚合可能不会出现在UPDATE语句的集合列表中。