慢速存储过程 - SQL Server

Posted

技术标签:

【中文标题】慢速存储过程 - SQL Server【英文标题】:Slow stored procedure - SQL Server 【发布时间】:2014-05-10 13:03:10 【问题描述】:

所以我创建了一个存储过程以在我的 VB.NET 程序中使用。这将检查是否存在多个表,然后创建相关表并使用数据库中的其他表将数据插入其中。最初我的存储过程运行得很好,但我最近对其进行了一些更改,现在运行需要超过 5 分钟,这导致我制作的程序出现问题,因为时间延迟导致它冻结。因此我需要减少执行存储过程所需的时间。下面我确定了需要很长时间的存储过程的两个部分。它们是:

Customers1 表

    IF EXISTS (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Customers1') 
drop table Customers1

Create Table Customers1
(ID int identity(1,1),
 [AccountNumber] NVARCHAR(20),
 [AddressNo] int,
 [Name] NVARCHAR(50),
 [Address] NVARCHAR(50),
 [Address2] NVARCHAR(50),
 [Town] NVARCHAR(50), 
 [County] nvarchar(20),
 [Postcode] nvarchar(15),
 [Country] nvarchar(20),
 [Contact] nvarchar(81),
 [Phone] nvarchar(30),
 [FaxNo] NVARCHAR(30),
 [CurrentBalance] MONEY,
 [CreditLimit] MONEY,
 [Rep] NVARCHAR (50),
 [EmailAddress] NVARCHAR(225),
 [shiptoid] int default(0))

insert into Customers1([AccountNumber], [AddressNo],[Name],[Address],[Address2],[Town],[County],[Postcode],[Country],[Contact],[Phone],[FaxNo],[CurrentBalance],[CreditLimit],[Rep],[EmailAddress],[shiptoid])
select
[AccountNumber]
,0 as AddressNo
,[Company]
,[Address]
,[Address2]
,[city]
,[State]
,[ZIP]
,[Country]
,[FirstName]+ ' ' +[lastname]
,[PhoneNumber]
,[FaxNumber]
,[AccountBalance]
,[CreditLimit]
,case when customtext2 = '' then 'HOUSE' else customtext2 end AS Rep
,EmailAddress
,0
from customer

union all

select
[AccountNumber]
,0 as AddressNo
,shipto.[Company]
,shipto.[Address]
,shipto.[Address2]
,shipto.[city]
,shipto.[State]
,shipto.[ZIP]
,shipto.[Country]
,customer.[FirstName]+ ' ' +customer.[lastname]
,shipto.[PhoneNumber]
,shipto.[FaxNumber]
,customer.[AccountBalance]
,customer.[CreditLimit]
,case when customtext2 = '' then 'HOUSE' else customtext2 end AS Rep
,customer.EmailAddress
,shipto.id
from customer left join shipto
on customer.id= shipto.customerid
where shipto.company is not null
order by customer.accountnumber

declare @tableid int
declare @lasttableid int
declare @AccountNumber nvarchar(25)
declare @LineNumber int

set @tableID = 1
set @lasttableID = (select max([id]) from Customers1)
set @LineNumber = 1
set @AccountNumber = (select AccountNumber from customers1 where id = @tableid)

while @tableID <= @lasttableid
begin
    while @AccountNumber = (select AccountNumber from Customers1 where id = @tableid)  
        begin
            update Customers1
            set [AddressNo] = @LineNumber
            where [id] = @tableid
            set @LineNumber = @LineNumber + 1
            set @tableid = @tableid + 1
        end
    set @LineNumber = 1
    set @AccountNumber = (select AccountNumber from customers1 where id = @tableid)
end

Orderlinehistory1 表

IF EXISTS (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'OrderLineHistory1') 
drop table OrderLineHistory1    

Create Table OrderLineHistory1
(ID int identity(1,1),
 [OrderNumber] nvarchar(25),
 [LineNo] INT,
 [ProductCode] nvarchar(25),
 [DueDate] DATETIME,
 [GrossSellingPrice] money,
 [OrderedQty] float,
 [DeliveredQty] float)

insert into OrderLineHistory1([OrderNumber],[LineNo],[ProductCode],[DueDate],[GrossSellingPrice],[OrderedQty],[DeliveredQty])
--select 
--purchaseorder.ponumber
--,0 as [LineNo]
--,item.itemlookupcode
--,Purchaseorder.RequiredDate
--,item.price
--,purchaseorderentry.quantityordered
--,purchaseorderentry.quantityreceivedtodate

--from PurchaseOrder,PurchaseOrderEntry,item
--where PurchaseOrder.id = PurchaseOrderEntry.PurchaseOrderID
--and purchaseorderentry.itemid = item.id
--and purchaseorder.potype = 0
--order by purchaseorder.ponumber,purchaseorderentry.id

select 
[orderentry].orderID
,0 as [LineNo]
,item.itemlookupcode
,[order].expirationorduedate
,orderentry.price
,orderentry.quantityonorder + orderentry.quantityRTD
,orderentry.quantityRTD
from orderentry left join [order] on orderentry.orderid = [order].ID
                left join item on orderentry.itemid = item.id
where orderentry.orderid >= (select min([ordernumber]) from pastorders)
order by [orderentry].orderID, [orderentry].ID                


declare @tableid1 int
declare @lasttableid1 int
declare @OrderNumber1 nvarchar(25)
declare @LineNumber1 int

set @tableID1 = 1
set @lasttableID1 = (select max([id]) from OrderLineHistory1)
set @LineNumber1 = 1
set @OrderNumber1 = (select OrderNumber from OrderLineHistory1 where id = @tableid1)

while @tableID1 <= @lasttableid1
begin
    while @OrderNumber1 = (select OrderNumber from OrderLineHistory1 where id = @tableid1)  
        begin
            update OrderLineHistory1
            set [LineNo] = @LineNumber1
            where [id] = @tableid1
            set @LineNumber1 = @LineNumber1 + 1
            set @tableid1 = @tableid1 + 1
        end
    set @LineNumber1 = 1
    set @OrderNumber1 = (select OrderNumber from OrderLineHistory1 where id = @tableid1)
end

有人能想出一种更有效的方法来编写这些吗?谢谢

整个存储过程:

ALTER Procedure sp_retreatHomes
AS
--SET NOCOUNT ON

IF EXISTS (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'FamilyCode') 
drop table FamilyCode

Create Table FamilyCode
(ID int identity(1,1),
 [Code] nvarchar(17),
 [Name] nvarchar(30))

insert into FamilyCode([code],[name])
values ('Code','Name')

insert into FamilyCode([code],[name])

select Code,[name]
from category

union
select Code,[name]
from department
order by [name] 

IF EXISTS (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Customers1') 
drop table Customers1

Create Table Customers1
(ID int identity(1,1),
 [AccountNumber] NVARCHAR(20),
 [AddressNo] int,
 [Name] NVARCHAR(50),
 [Address] NVARCHAR(50),
 [Address2] NVARCHAR(50),
 [Town] NVARCHAR(50), 
 [County] nvarchar(20),
 [Postcode] nvarchar(15),
 [Country] nvarchar(20),
 [Contact] nvarchar(81),
 [Phone] nvarchar(30),
 [FaxNo] NVARCHAR(30),
 [CurrentBalance] MONEY,
 [CreditLimit] MONEY,
 [Rep] NVARCHAR (50),
 [EmailAddress] NVARCHAR(225),
 [shiptoid] int default(0))

insert into Customers1([AccountNumber], [AddressNo],[Name],[Address],[Address2],[Town],[County],[Postcode],[Country],[Contact],[Phone],[FaxNo],[CurrentBalance],[CreditLimit],[Rep],[EmailAddress],[shiptoid])
select
[AccountNumber]
,0 as AddressNo
,[Company]
,[Address]
,[Address2]
,[city]
,[State]
,[ZIP]
,[Country]
,[FirstName]+ ' ' +[lastname]
,[PhoneNumber]
,[FaxNumber]
,[AccountBalance]
,[CreditLimit]
,case when customtext2 = '' then 'HOUSE' else customtext2 end AS Rep
,EmailAddress
,0
from customer

union all

select
[AccountNumber]
,0 as AddressNo
,shipto.[Company]
,shipto.[Address]
,shipto.[Address2]
,shipto.[city]
,shipto.[State]
,shipto.[ZIP]
,shipto.[Country]
,customer.[FirstName]+ ' ' +customer.[lastname]
,shipto.[PhoneNumber]
,shipto.[FaxNumber]
,customer.[AccountBalance]
,customer.[CreditLimit]
,case when customtext2 = '' then 'HOUSE' else customtext2 end AS Rep
,customer.EmailAddress
,shipto.id
from customer left join shipto
on customer.id= shipto.customerid
where shipto.company is not null
order by customer.accountnumber

declare @tableid int
declare @lasttableid int
declare @AccountNumber nvarchar(25)
declare @LineNumber int

set @tableID = 1
set @lasttableID = (select max([id]) from Customers1)
set @LineNumber = 1
set @AccountNumber = (select AccountNumber from customers1 where id = @tableid)

while @tableID <= @lasttableid
begin
    while @AccountNumber = (select AccountNumber from Customers1 where id = @tableid)  
        begin
            update Customers1
            set [AddressNo] = @LineNumber
            where [id] = @tableid
            set @LineNumber = @LineNumber + 1
            set @tableid = @tableid + 1
        end
    set @LineNumber = 1
    set @AccountNumber = (select AccountNumber from customers1 where id = @tableid)
end



IF EXISTS (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'CatalogueProducts1') 
drop table CatalogueProducts1

Create Table CatalogueProducts1 
(ID int identity(1,1),
 [CatalogueCode] nvarchar(25),
 [ProductCode] nvarchar(25),
 [DisplaySequence] int)

insert into CatalogueProducts1([CatalogueCode],[ProductCode], [DisplaySequence])

SELECT case when left(SubDescription1,4) = '' then 'NA' else left(SubDescription1,4) end
,[ItemLookupCode]
,0
from dbo.Item
Order by left(SubDescription1,4) asc

declare @tableid2 int
declare @lasttableid2 int
declare @CatalogueCode nvarchar(25)
declare @DisplaySequence int

set @tableID2 = 1
set @lasttableID2 = (select max([id]) from CatalogueProducts1)
set @DisplaySequence = 1
set @CatalogueCode = (select CatalogueCode from CatalogueProducts1 where id = @tableid2)

while @tableID2 <= @lasttableid2
begin
    while @CatalogueCode = (select CatalogueCode from CatalogueProducts1 where id = @tableid2)  
        begin
            update CatalogueProducts1
            set [DisplaySequence] = @DisplaySequence
            where [id] = @tableid2
            set @DisplaySequence = @DisplaySequence + 1
            set @tableid2 = @tableid2 + 1
        end
    set @DisplaySequence = 1
    set @CatalogueCode = (select CatalogueCode from CatalogueProducts1 where id = @tableid2)
end

IF EXISTS (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'CatalogueProducts') 
drop table CatalogueProducts

Create Table CatalogueProducts 
(ID int identity(1,1),
 [CatalogueCode] nvarchar(25),
 [ProductCode] nvarchar(25),
 [DisplaySequence] nvarchar(25))

insert into CatalogueProducts([CatalogueCode],[ProductCode], [DisplaySequence])  
values('CatalogueCode','ProductCode', 'DisplaySequence')

insert into CatalogueProducts([CatalogueCode],[ProductCode], [DisplaySequence])  
select CatalogueCode,ProductCode,convert(nvarchar,DisplaySequence)
from CatalogueProducts1
order by id


IF EXISTS (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'PastOrders') 
drop table PastOrders

Create Table PastOrders
(ID int identity(1,1),
 [OrderNumber] NVARCHAR(25),
 [AccountCode] nvarchar(20),
 [AddressNo] nvarchar(10),
 [OrderDate] NVARCHAR(50),
 [DueDate] NVARCHAR(50),
 [RepCode] NVARCHAR(50))
insert into PastOrders([OrderNumber],[AccountCode],[AddressNo],[OrderDate],[DueDate],[RepCode]) 
values ('OrderNumber','AccountCode','AddressNo','OrderDate','DueDate','RepCode')

insert into PastOrders([OrderNumber],[AccountCode],[AddressNo],[OrderDate],[DueDate],[RepCode])

SELECT 
CONVERT(VARCHAR,[Order].ID) AS OrderNumber
,Customer.AccountNumber
,case when shiptoid = 0 then 1 else shiptoid end AS AddressNo
,isnull(convert(nvarchar,(datepart(dd,[order].ExpirationOrDueDate))) 
+ '/' + convert(nvarchar,(datepart(mm,[order].ExpirationOrDueDate)))
+ '/' + convert(nvarchar,(datepart(yy,[order].ExpirationOrDueDate))),'')
,isnull(convert(nvarchar,(datepart(dd,[order].LastUpdated))) 
+ '/' + convert(nvarchar,(datepart(mm,[order].LastUpdated)))
+ '/' + convert(nvarchar,(datepart(yy,[order].LastUpdated))),'')
,case when customer.customtext2 = '' then 'HOUSE' else customer.customtext2 end
FROM [Order]
LEFT JOIN Customer ON [order].customerID = customer.ID
where Customer.AccountNumber is not null
and [order].[time] > (select getdate() - 550)



update PastOrders
set [AddressNo] = convert(nvarchar,customers1.addressno)
from PastOrders,customers1
where PastOrders.[AddressNo] = customers1.shiptoid
and PastOrders.[AddressNo] <> 'AddressNo' 

update PastOrders
set [AddressNo] = 1
where [AddressNo] not in (select id from shipto)
and PastOrders.[AddressNo] <> 'AddressNo' 







--fix customers
IF EXISTS (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Customers') 
drop table Customers

Create Table Customers
(ID int identity(1,1),
 [AccountNumber] NVARCHAR(20),
 [AddressNo] nvarchar(30),
 [Name] NVARCHAR(50),
 [Address] NVARCHAR(50),
 [Address2] NVARCHAR(50),
 [Town] NVARCHAR(50), 
 [County] nvarchar(20),
 [Postcode] nvarchar(15),
 [Country] nvarchar(20),
 [Contact] nvarchar(81),
 [Phone] nvarchar(30),
 [FaxNo] NVARCHAR(30),
 [CurrentBalance] NVARCHAR(225),
 [CreditLimit] NVARCHAR(225),
 [Rep] NVARCHAR (255),
 [EmailAddress] NVARCHAR(225))

insert into Customers([AccountNumber], [AddressNo],[Name],[Address],[Address2],[Town],[County],[Postcode],[Country],[Contact],[Phone],[FaxNo],[CurrentBalance],[CreditLimit],[Rep],[EmailAddress])
values ('AccountNumber', 'AddressNo','Name','Address','Address2','Town','County','Postcode','Country','Contact','Phone','FaxNo','CurrentBalance','CreditLimit','Rep','EmailAddress')


insert into Customers([AccountNumber], [AddressNo],[Name],[Address],[Address2],[Town],[County],[Postcode],[Country],[Contact],[Phone],[FaxNo],[CurrentBalance],[CreditLimit],[Rep],[EmailAddress])
select [AccountNumber],
convert(nvarchar,[AddressNo])
,[Name]
,[Address]
,[Address2]
,[Town]
,[County]
,[Postcode]
,[Country]
,[Contact]
,[Phone]
,[FaxNo]
,convert(nvarchar,[CurrentBalance])
,convert(nvarchar,[CreditLimit])
,[Rep]
,[EmailAddress]
from customers1
order by [id] asc


IF EXISTS (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Products') 
drop table Products

Create Table Products
(ID int identity(1,1),
 [ProductCode] NVARCHAR(25),
 [Description] NVARCHAR(30),
 [UOM] NVARCHAR(4),
 [Carton] NVARCHAR(30),
 [StdPrice] NVARCHAR(25),
  [SalesPrice] NVARCHAR(25),
 [StockQty] NVARCHAR(25),
 [PODueIn] NVARCHAR(25),
 [OnSOQty] NVARCHAR(25),
 [DueDate] NVARCHAR(25),
 [Barcode] NVARCHAR(25),
 [FamilyCode1] NVARCHAR(30),
 [FamilyCode2] NVARCHAR(30))


 insert into Products([ProductCode]
,[Description]
,[UOM]
,[Carton]
,[StdPrice]
,[SalesPrice]
,[StockQty]
,[PODueIn]
,[OnSOQty]
,[DueDate]
,[Barcode]
,[FamilyCode1]
,[FamilyCode2])

Values('ProductCode','Description','UOM','Carton','StdPrice','SalesPrice','StockQty','PODueIn','OnSOQty','DueDate','Barcode','FamilyCode1','FamilyCode2') 

insert into Products([ProductCode]
,[Description]
,[UOM]
,[Carton]
,[Barcode]
,[StdPrice]
,[StockQty]
,[PODueIn]
,[OnSOQty]
,[DueDate]
,[FamilyCode1]
,[FamilyCode2]
,[SalesPrice])

select [ItemLookupCode]
,[Description]
,CASE [UnitOfMeasure] WHEN '' THEN 'EACH' ELSE UnitOfMeasure END AS UOM
,[SubDescription3]
, [Alias]
, convert(nvarchar,item.[Price])
, convert(nvarchar,item.[quantity])
, isnull(View_PO.PODueIn,0) as PODueIN
, convert(nvarchar,item.[QuantityCommitted])
, isnull(convert(nvarchar,(datepart(dd,View_PO.DueDate))) 
+ '/' + convert(nvarchar,(datepart(mm,View_PO.DueDate)))
+ '/' + convert(nvarchar,(datepart(yy,View_PO.DueDate))),'') as DueDate
, isnull(department.[name],'') as Department
, isnull(category.[name],'') as Category
, convert(nvarchar,item.[SalePrice])
from Item 
LEFT JOIN Alias ON alias.ItemID = Item.id
left join View_PO on item.id = View_PO.itemid
inner join firstAlias on alias.ID=firstAlias.id and firstAlias.ItemID=item.id
left join department on item.departmentid = department.id
left join category on item.categoryid = category.id
WHERE SubDescription3 NOT IN ('0','')
order by item.id asc



IF EXISTS (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'OrderLineHistory1') 
drop table OrderLineHistory1    

Create Table OrderLineHistory1
(ID int identity(1,1),
 [OrderNumber] nvarchar(25),
 [LineNo] INT,
 [ProductCode] nvarchar(25),
 [DueDate] DATETIME,
 [GrossSellingPrice] money,
 [OrderedQty] float,
 [DeliveredQty] float)

insert into OrderLineHistory1([OrderNumber],[LineNo],[ProductCode],[DueDate],[GrossSellingPrice],[OrderedQty],[DeliveredQty])
--select 
--purchaseorder.ponumber
--,0 as [LineNo]
--,item.itemlookupcode
--,Purchaseorder.RequiredDate
--,item.price
--,purchaseorderentry.quantityordered
--,purchaseorderentry.quantityreceivedtodate

--from PurchaseOrder,PurchaseOrderEntry,item
--where PurchaseOrder.id = PurchaseOrderEntry.PurchaseOrderID
--and purchaseorderentry.itemid = item.id
--and purchaseorder.potype = 0
--order by purchaseorder.ponumber,purchaseorderentry.id

select 
[orderentry].orderID
,0 as [LineNo]
,item.itemlookupcode
,[order].expirationorduedate
,orderentry.price
,orderentry.quantityonorder + orderentry.quantityRTD
,orderentry.quantityRTD
from orderentry left join [order] on orderentry.orderid = [order].ID
                left join item on orderentry.itemid = item.id
where orderentry.orderid >= (select min([ordernumber]) from pastorders)
order by [orderentry].orderID, [orderentry].ID                


declare @tableid1 int
declare @lasttableid1 int
declare @OrderNumber1 nvarchar(25)
declare @LineNumber1 int

set @tableID1 = 1
set @lasttableID1 = (select max([id]) from OrderLineHistory1)
set @LineNumber1 = 1
set @OrderNumber1 = (select OrderNumber from OrderLineHistory1 where id = @tableid1)

while @tableID1 <= @lasttableid1
begin
    while @OrderNumber1 = (select OrderNumber from OrderLineHistory1 where id = @tableid1)  
        begin
            update OrderLineHistory1
            set [LineNo] = @LineNumber1
            where [id] = @tableid1
            set @LineNumber1 = @LineNumber1 + 1
            set @tableid1 = @tableid1 + 1
        end
    set @LineNumber1 = 1
    set @OrderNumber1 = (select OrderNumber from OrderLineHistory1 where id = @tableid1)
end


IF EXISTS (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'OrderLineHistory') 
drop table OrderLineHistory 

Create Table OrderLineHistory
(ID int identity(1,1),
 [OrderNumber] nvarchar(25),
 [LineNo] nvarchar(25),
 [ProductCode] nvarchar(25),
 [DueDate] nvarchar(25),
 [GrossSellingPrice]nvarchar(25),
 [OrderedQty] nvarchar(25),
 [DeliveredQty] nvarchar(25))

insert into OrderLineHistory([OrderNumber],[LineNo],[ProductCode],[DueDate],[GrossSellingPrice],[OrderedQty],[DeliveredQty])
values('OrderNumber','LineNo','ProductCode','DueDate','GrossSellingPrice','OrderedQty','DeliveredQty')  

insert into OrderLineHistory([OrderNumber],[LineNo],[ProductCode],[DueDate],[GrossSellingPrice],[OrderedQty],[DeliveredQty])
select [OrderNumber],convert(varchar(25),[LineNo]),[ProductCode]
,isnull(convert(nvarchar,(datepart(dd,DueDate))) 
+ '/' + convert(nvarchar,(datepart(mm,DueDate)))
+ '/' + convert(nvarchar,(datepart(yy,DueDate))),'')
,[GrossSellingPrice],[OrderedQty],[DeliveredQty]
from OrderLineHistory1
order by id asc 

-- Reps
IF EXISTS (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Reps') 
drop table Reps

Create Table Reps
(ID int identity(1,1),
 [Code] nvarchar(17),
 [Name] nvarchar(30))

insert into Reps([code],[Name])
values ('Code','Name')

insert into Reps([code],[Name])
select distinct customtext2,customtext2
from customer
where customtext2 <> ''
order by customtext2

--Catalogues
IF EXISTS (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Catalogues') 
drop table Catalogues

Create Table Catalogues
(ID int identity(1,1),
 [Code] nvarchar(17),
 [Description] nvarchar(30))

insert into Catalogues([code],[Description])
values ('Code','Description')

insert into Catalogues([code],[Description])
select  distinct left(subdescription1,4),subdescription1  
from item
where subdescription1 <> ''

union

select 'NA', 'Not Assigned'
order by subdescription1



-- select * from reps
-- select * from Catalogues
-- select * from FamilyCode
-- select * from CatalogueProducts
-- select * from customers
-- select * from products
-- select * from pastorders
-- select * from orderlinehistory   

【问题讨论】:

只是为了让人们知道他 OrderLineHistory1 表导致了主要问题,它需要大约 5 分钟才能运行,customers1 表需要大约 30 秒,但我仍然可以这样做更有效率跨度> 您做了哪些更改导致您的 SP 开始运行缓慢? 您的表:orderentry、order、pastorders 是否在您要加入的列上编入索引? @I.K.我对其进行了更改,因此它包含了 while 循环,我认为因为数据库中有太多记录,这就是为什么它需要这么长时间。也许有一种方法可以编写 SQL 以使 while 循环更有效,或者我可以编写一些与 while 循环执行相同操作但更快的方法? 啊!当然,在大桌子上循环会影响你的表现。如果可以的话,最好使用基于集合的查询来重写。你想用 while 循环来实现什么,也许我可以帮忙。 【参考方案1】:

我认为您可以只使用一个 while 循环来重写循环逻辑。我不能肯定地说,因为我不知道您的确切业务需求,也无法测试任何数据。试试看,让我知道:

set @tableID = 1
set @lasttableID = (select max([id]) from Customers1)
set @LineNumber = 1
set @AccountNumber = (select AccountNumber from customers1 where id = @tableid)

while @AccountNumber = (select AccountNumber 
                        from Customers1 
                        where id = @tableid)  
begin
    update Customers1
    set [AddressNo] = @LineNumber
    where [id] = @tableid

    set @LineNumber = @LineNumber + 1
    set @tableid = @tableid + 1
    set @AccountNumber = (select AccountNumber from customers1 where id = @tableid)

    if (@tableId <= @lasttableid)
        BREAK
    else
        CONTINUE
end

【讨论】:

这只是为客户 1 表吗? :) 谢谢你的帮助 :) 基本上你的while循环遵循类似的模式。在所有情况下都应用上述内容,并让我知道它是否加快了 SP。还可以尝试我之前提到的其他策略。但是一次尝试一个,尝试更改循环查询以遵循模式,测试它。如果不行,那么添加我之前提到的索引。如果不行,则拆分SP。在那之后,您可能需要真正以完全不同的方式解决问题。 此外,一旦我用上面的代码替换了以前的 Customers1 代码,由于某种原因它运行速度较慢:/ 我认为我可以使用基于集合的查询而不是 while 循环,我只是不这样做不知道怎么写 在id列给customers1添加索引并告诉我 不过我已经在我的 orderlinehistory1 表上尝试过这种方法,它似乎已经减少了,让我比较一下之前和现在的数据

以上是关于慢速存储过程 - SQL Server的主要内容,如果未能解决你的问题,请参考以下文章

sql server中怎样创建保存数据的存储过程

怎样在Sql server中创建,执行和删除存储过程

SQL Server基础之存储过程

sql server 存储过程如何调用存储过程

SQL Server 存储过程

sql server 一个简单的存储过程