技术开发 频道

游标脚本性能问题详解之案例实践篇

  接下来我们分析两个脚本的执行计划:

  1. dynamic游标对应的不理想的执行计划中,SQL Server选择了索引扫描(index scan)及索引S_AUDIT_ITEM_M4来查阅S_AUDIT_ITEM表。因此我们会在这里看到大量的IO。

尝试解决问题

  这个索引扫描实际上访问了整张表的数据。

  2.而fast forward only游标对应的理想的执行计划中,SQL Server选择的是索引查找(index seek)及索引S_AUDIT_ITEM_M3来查阅S_AUDIT_ITEM表。所以我们只看到3个逻辑读。索引S_AUDIT_ITEM_M3包含4个列,第一个列是RECORD_ID。另外,在语句中,有WHERE条件T1.RECORD_ID=@P2
 

尝试解决问题

  四、尝试解决问题

  首先我们尝试更新统计信息:UPDATE STATISTICS ON S_AUDIT_ITEM WITH FULLSCAN,但是这个操作在此问题案例中没有作用。

  从以上的分析中,我们已经发现,如果使用index S_AUDIT_ITEM_M3访问S_AUDIT_ITEM表,得到的执行计划非常好,我们可以直接用index hint来解决这个问题:

declare @p1 int set @p1=NULL

  declare @p2
int set @p2=0

  declare @p5
int set @p5=4098

  declare @p6
int set @p6=8193

  declare @p7
int set @p7=0

  exec sp_cursorprepexec @p1 output,@p2 output,N
'@P1 varchar(30),@P2 varchar(15)',

  N
'

  
SELECT T1.CONFLICT_ID

  FROM dbo.S_AUDIT_ITEM T1
with (INDEX=S_AUDIT_ITEM_M3) /* 解决方案2 */

  
LEFT OUTER JOIN dbo.S_USER T2

  
ON T1.USER_ID = T2.PAR_ROW_ID

  WHERE ((T1.BC_BASE_TBL
= @P1)

  
AND (T1.RECORD_ID = @P2))

  ORDER BY T1.OPERATION_DT DESC

  
OPTION (FAST 40)

  
',

  @p5 output,@p6 output,@p7 output,
'1-10350J','S_PARTY'

  print
'fetch'

  exec sp_cursorfetch @p2,
2,4,1

  exec sp_cursorclose @p2
0
相关文章