gru*_*ber 1 sql t-sql sql-server sql-server-2008
我有一个非常大的脚本,它使用游标和嵌套游标.
我遇到了性能问题,我发现脚本中的最后一条指令完成了main while循环占用了大部分时间:
SET STATISTICS TIME ON
FETCH NEXT FROM OldMetaOffer_cursor
INTO @MetaOfferId, @CustomerId, @OfferName, @CheckedOutById, @CheckOutDate, @LastOfferStatusId, @LastCalculationNumber, @CreatedByDisplayName, @CreatedById, @CreateDate, @CoordinatorId, @CoordinatorDate, @CentralAnalystId, @CentralAnalystDate, @DeployUserId, @DeploymentDate, @OwnerId;
SET STATISTICS TIME OFF
Run Code Online (Sandbox Code Playgroud)
它需要超过4秒,而一步完成需要4,6秒
表MetaOffer有大约150 k行但我在8,5 k行上使用游标.(我在开头过滤行).
有没有办法改善这种糟糕的表现?
在循环开始时我有:
DECLARE @MetaOfferId uniqueidentifier
, @MetaOfferTypeId int
, @CustomerId uniqueidentifier -- CustomerId
, @OfferName nvarchar(50) -- OfferName
, @CheckedOutById int -- CheckOutById
, @CheckOutDate datetime -- CheckOutDate
, @LastOfferStatusId int -- LastProcessStatusId
, @LastCalculationNumber nvarchar(20) -- LastCalculationNumber
, @CreatedByDisplayName nvarchar(300) -- CreatedByDisplayName
, @CreatedById int -- CreatedById
, @CreateDate datetime -- CreateDate
, @CoordinatorId int -- CoordinatorId
, @CoordinatorDate datetime -- CoordinatorDate
, @CentralAnalystId int -- CentralAnalystId
, @CentralAnalystDate datetime -- CentralAnalystDate
, @DeployUserId int -- DeployUserId
, @DeploymentDate datetime -- DeploymentDate
, @OwnerId int -- OwnerId
-- id statusu po zmapowaniu
, @NewLastOfferStatusId int
DECLARE OldMetaOffer_cursor CURSOR FOR
SELECT MetaOfferId, CustomerId, OfferName, CheckedOutById, CheckOutDate, LastOfferStatusId, LastCalculationNumber, CreatedByDisplayName, CreatedById,
CreateDate, CoordinatorId, CoordinatorDate, CentralAnalystId, CentralAnalystDate, DeployUserId, DeploymentDate, OwnerId
FROM [Other].[dbo].[MetaOffer] MO where
exists
(select * from [Other].[dbo].[OfferHistoryItem]
where MetaOfferId = MO.MetaOfferId and NewStatusId = 9 and DiscountId is null and KoosOfferId is null)
Run Code Online (Sandbox Code Playgroud)
也许有一个问题,在下一次获取此查询再次进行?结果在任何地方都没有缓冲.如果是这样,我可以通过任何方式获得该查询的结果并对数据进行操作而不对每个循环步骤进行查询?
由于你遗漏了问题最重要的部分(游标实际上做了什么),我只是给你这个参考,希望能告诉你如何在没有游标的情况下完成你的任务.游标表现极差,如果存在任何其他替代方案,则不应使用游标.我曾经通过移除光标将过程从45分钟更改为不到1分钟,另一个过程从24小时变为大约30分钟.使用游标的原因很少,很多不使用游标.它们是最后的技术,而不是你尝试的第一件事.
http://wiki.lessthandot.com/index.php/Cursors_and_How_to_Avoid_Them
| 归档时间: |
|
| 查看次数: |
2572 次 |
| 最近记录: |