Sql server 如何优化游标使用的查询?

Sql server 如何优化游标使用的查询?,sql-server,optimization,cursor,query-optimization,sql-execution-plan,Sql Server,Optimization,Cursor,Query Optimization,Sql Execution Plan,我有一个使用以下游标的存储过程: 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 n

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

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]
但是,执行仍然花费了太多的时间(您可以在附件中找到执行计划)

谢谢


真正的问题可能是:您真的需要光标吗,特别是在查询计划中显示的“fat”行的情况下

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


另外,对存储过程的其余部分一无所知:如果您碰巧正在更新游标循环中的
[ODS_PFNUM_DELAI]
表,并且更改不会影响实际循环,那么最好将游标定义为
静态

,真正的问题可能是:您真的需要游标吗,特别是考虑到查询计划中显示的“fat”行

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


另外,对存储过程的其余部分一无所知:如果您碰巧正在更新游标循环中的
[ODS_PFNUM_DELAI]
表,并且更改不会影响实际循环,那么如果您使用2012或2014,最好将游标定义为
静态

,通过使用窗口函数,您可以完全替换光标。这将大大提高性能。像Lag、Lead和unbound previous谓词这样的函数将成为您的朋友。@Nelp不幸的是,我使用的是SQL Server 2008。谢谢你的回复!这是非常罕见的,你真的需要一个光标,你能提供多一点背景,这样也许我们可以优化光标。您会发现,基于集合的查询通常比RBAR(一行一行)快得多。如果您使用2012或2014,则可以使用窗口函数完全替换光标。这将大大提高性能。像Lag、Lead和unbound previous谓词这样的函数将成为您的朋友。@Nelp不幸的是,我使用的是SQL Server 2008。谢谢你的回复!这是非常罕见的,你真的需要一个光标,你能提供多一点背景,这样也许我们可以优化光标。您会发现,基于集合的查询通常比RBAR(逐行查询)快得多。
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