【问题标题】:How can I optimize this query used by a cursor?如何优化游标使用的此查询?
【发布时间】:2016-02-11 05:21:35
【问题描述】:

我有一个使用以下光标的存储过程:

DECLARE Delai_latence CURSOR LOCAL FOR 
SELECT [ID]
      ,[ID_LIVRAISON]
      ,[DH_ETAPE_DEB]
      ,[DH_ETAPE_FIN]
      ,[ORDRE_ETAPE]
FROM [ODS_PFNUM_DELAI]
WHERE ID_GRP = 1
  AND STATUT_ETAPE is not Null
  AND DH_ETAPE_FIN is not Null
ORDER BY [ID_LIVRAISON], [ORDRE_ETAPE]

为了优化,我创建了非聚集索引:

CREATE NONCLUSTERED INDEX [IX_LATENCE_PFNUM_DELAI] ON [ODS_PFNUM_DELAI] 
(
    [ID_GRP] ASC,
    [STATUT_ETAPE] ASC,
    [DH_ETAPE_FIN] ASC
)
INCLUDE ( [ID],
[ID_LIVRAISON],
[DH_ETAPE_DEB],
[ORDRE_ETAPE]) WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]

但是,执行仍然需要太多时间(您会发现附件中的执行计划)。

谢谢。

ExecutionPlan.jpg

【问题讨论】:

  • 如果您使用的是 2012 或 2014,您可以使用窗口函数完全替换光标。这可能会给您带来很大的性能提升。 Lag、Lead 和未绑定的前置谓词等函数将成为您的朋友。
  • @NeilP 不幸的是,我使用的是 SQL Server 2008。无论如何感谢您的回复!
  • 真正需要游标的情况很少见,能否提供更多背景信息,以便我们优化游标。您会发现基于集合的查询而不是 RBAR(逐行逐行)通常要快得多。

标签: sql-server optimization cursor query-optimization sql-execution-plan


【解决方案1】:

真正的问题可能是:您真的需要光标吗,尤其是考虑到查询计划中显示的“胖”行。

无论如何,出于好奇,查询会从这个(过滤的)索引中受益吗?

CREATE INDEX idx_test ON [ODS_PFNUM_DELAI] 
       ([ID_GRP], [ID_LIVRAISON], [ORDRE_ETAPE]) 
INCLUDE ([ID], [DH_ETAPE_DEB], [DH_ETAPE_FIN])
WHERE [STATUT_ETAPE] IS NOT NULL AND [DH_ETAPE_FIN] IS NOT NULL 

另外,对存储过程的其余部分一无所知:如果您碰巧正在更​​新游标循环内的 [ODS_PFNUM_DELAI] 表并且更改不会影响实际循环,那么这可能是一个不错的选择将光标定义为STATIC的想法。

【讨论】:

    猜你喜欢
    • 2011-09-24
    • 1970-01-01
    • 2016-07-22
    • 2022-07-21
    • 2017-03-01
    • 2023-04-02
    • 1970-01-01
    相关资源
    最近更新 更多