优化游标性能

转载 2012年03月21日 13:19:58

最好的改进光标性能的技术就是:能避免时就避免使用游标。

——摘自《Transact-SQL权威指南》 Ken Henderson[著]

    最好的改进光标性能的技术就是:能避免时就避免使用游标。SQL Server是关系数据库,其处理数据集比处理单行好得多,单独行的访问根本不适合关系DBMS。若有时无法避免使用游标,则可以用如下技巧来优化游标的性能。
(1). 除非必要否则不要使用static/insensitive游标。打开static游标会造成所有的行都被拷贝到临时表。这正是为什么它对变化不敏感的原因——它实际上是指向临时数据库表中的一个备份。很自然,结果集越大,声明其上的static游标就会引起越多的临时数据库的资源争夺问题。
(2). 除非必要否则不要使用keyset游标。和static游标一样,打开keyset游标会创建临时表。虽然这个表只包括基本表的一个关键字列(除非不存在唯一关键字),但是当处理大结果集时还是会相当大的。
(3). 当处理单向的只读结果集时,使用fast_forward代替forward_only。使用fast_forward定义一个forward_only,则read_only游标具有一定的内部性能优化。
(4). 使用read_only关键字定义只读游标。这样可以防止意外的修改,并且让服务器了解游标移动时不会修改行。
(5). 小心事务处理中通过游标进行的大量行修改。根据事务隔离级别,这些行在事务完成或回滚前会保持锁定,这可能造成服务器上的资源争夺。
(6). 小心动态光标的修改,尤其是建在非唯一聚集索引键的表上的游标,因为他们会造成“Halloween”问题——对同一行或同一行的重复的错误的修改。因为SQL Server在内部会把某行的关键字修改成一个已经存在的值,并强迫服务器追加下标,使它以后可以再结果集中移动。当从结果集的剩余项中存取时,又会遇到那一行,然后程序会重复,结果造成死循环。
(7). 对于大结果集要考虑使用异步游标,尽可能地把控制权交给调用者。当返回相当大的结果集到可移动的表格时,异步游标特别有用,因为它们允许应用程序几乎马上就可以显示行。

Halloween:

CREATE Table #T(
    k1 int identity(1,1),
    c1 int null
);
 
CREATE CLUSTERED INDEX C1 ON #T(C1);
 
INSERT INTO #T(C1) VALUES(8)
INSERT INTO #T(C1) VALUES(6)
INSERT INTO #T(C1) VALUES(7)
INSERT INTO #T(C1) VALUES(5)
INSERT INTO #T(C1) VALUES(3)
INSERT INTO #T(C1) VALUES(0)
INSERT INTO #T(C1) VALUES(9)
 
 
DECLARE C CURSOR DYNAMIC
    FOR SELECT K1,C1 FROM #T;
 
OPEN C
FETCH C
WHILE(@@FETCH_Status=0)
BEGIN
    UPDATE #T SET C1=C1+1
        WHERE CURRENT OF C;
    FETCH C;
END
 
CLOSE C;
DEALLOCATE C;
 
DROP Table #T;
GO

相关文章推荐

优化游标性能

最好的改进光标性能的技术就是:能避免时就避免使用游标。 ——摘自《Transact-SQL权威指南》 Ken Henderson[著]     最好的改进光标性能的技术就是:能避免时就避免使用...

游标脚本性能问题解决与分析 (1) - Cursor Performance Analysis

第一部分:游标类型对性能影响的实例引出 下面的两个游标脚本分别创建并执行了dynamic和fast forward only两种类型的游标: 不理想的游标类型:(dynamic游标...
  • apgcdsd
  • apgcdsd
  • 2011年08月20日 18:12
  • 499

游标脚本性能问题解决与分析 (3) - Cursor Performance Analysis

第三部分、几种解决方法殊途同归 根据我们更多的分析和测试,以下几种方法都可以解决这个性能问题 1.        使用top 10 2.        使用with (INDEX=S_AUDIT...
  • apgcdsd
  • apgcdsd
  • 2011年08月30日 14:53
  • 324

使用bulk collect 和 forall 提高游标性能

当运行一个pl/sql程序时, pl/sql语句引擎会执行pl/sql语句。但如果在这个过程中引擎遇到sql语句,它会把这个语句传给sql引擎(后台发生上下文切换)。   在PL/SQL 和SQL引擎...
  • zj0078
  • zj0078
  • 2013年12月19日 08:47
  • 2979

oracle游标优化

  • 2010年08月17日 12:09
  • 466B
  • 下载

《基于ORACLE SQL优化》读书笔记-游标

show parameter open_cursors; --单个session可并存sessioncursor数   select count(*) from v$open_cursor whe...

Mysql存储过程优化——使用临时表代替游标

Mysql游标在操作小数据量时比较方便,效率可观,但操作大数据量,速度比较慢,甚至直接产生系统错误。 一般说来,当操作的数据超过1万条时,就避免用游标吧。 为了测试游标性能,写了下面一个游标对IDC_...

【Oracle 优化器】自适应游标共享(Adaptive Cursor Sharing)功能

本文主要介绍Oracle优化器的自适应游标共享(Adaptive Cursor Sharing)功能和处理流程。...

Mysql存储过程优化——使用临时表代替游标

Mysql游标在操作小数据量时比较方便,效率可观,但操作大数据量,速度比较慢,甚至直接产生系统错误。   一般说来,当操作的数据超过1万条时,就避免用游标吧。   为了测试游标...
  • Heng_Ji
  • Heng_Ji
  • 2014年07月22日 17:35
  • 5562
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:优化游标性能
举报原因:
原因补充:

(最多只允许输入30个字)