sql-server – 游标有什么问题?

除了在某些情况下,sql Server开发人员认为游标是一种不好的做法.他们认为,游标不会最佳地使用sql引擎,因为它是一个程序性的构造,并且击败了基于Set的RDBMS概念.

但是,Oracle开发人员似乎并不推荐使用光标. Oracle的DML语句本身是隐式游标.

为什么这种差异的方法?是因为这两种产品的制造方式,还是这种建议适用于这两种产品?

解决方法

游标出现的问题是在Oracle和MS sql中都经常被滥用.

光标用于保持稳定的结果集,您可以逐行检索.当您的查询运行时,它们是隐式创建的,并在完成查询关闭.

当然,保留这样的结果集需要一些资源:锁,锁存器,内存,甚至磁盘空间.

这些资源越快越好.

保持光标打开就像保持冰箱门打开

你不要在几个小时没有必要,但这并不意味着你不应该打开你的冰箱.

这意味着:

>你不会逐行得到结果,并且总结出来:你调用sql的SUM.
>您不执行整个查询并从游标获取第一个结果:您将rownum< = 10条件附加到查询
等等

对于Oracle,在一个过程中处理你的游标需要臭名昭着的sql / PLsql上下文切换,每当你从游标中得到SQL查询的结果时,它就会发生.

它涉及在线程之间传递大量数据并同步线程.

这是Oracle中最令人激动的事情之一.

这种行为的不太明显的后果之一是如果可能,应该避免Oracle中的触发器.

创建触发器并调用DML函数等于打开游标,选择更新的行并为该游标的每一行调用触发器代码.

触发器的存在(甚至是空触发器)可能会减慢DML操作10次或更多次.

10g上的测试脚本:

sql> CREATE TABLE trigger_test (id INT NOT NULL)
  2  /

Table created

Executed in 0,031 seconds
sql> INSERT
  2  INTO   trigger_test
  3  SELECT level
  4  FROM   dual
  5  CONNECT BY
  6     level <= 1000000
  7  /

1000000 rows inserted

Executed in 1,469 seconds
sql> COMMIT
  2  /

Commit complete

Executed in 0 seconds
sql> TRUNCATE TABLE trigger_test
  2  /

Table truncated

Executed in 3 seconds
sql> CREATE TRIGGER trg_test_ai
  2  AFTER INSERT
  3  ON trigger_test
  4  FOR EACH ROW
  5  BEGIN
  6     NULL;
  7  END;
  8  /

Trigger created

Executed in 0,094 seconds
sql> INSERT
  2  INTO   trigger_test
  3  SELECT level
  4  FROM   dual
  5  CONNECT BY
  6     level <= 1000000
  7  /

1000000 rows inserted

Executed in 17,578 seconds

1.47秒没有触发,17.57秒用空触发器什么也没做.

相关文章

(一)日志传送架构 (1.1)相关服务器 主服务器 :用于生产的服务器,上面运行这生产SQL Server数据库...
(一)事故背景 最近在SQL Server 2012生产数据库上配置完事物复制(发布订阅)后,生产数据库业务出现了...
(一)测试目的 目前公司使用的SQL SERVER 2012高可用环境为主备模式,其中主库可执行读写操作,备库既...
(一)背景个人在使用sql server时,用到了sql server的发布订阅来做主从同步,类似MySQL的异步复制。在...
UNION和OR谓词 找出 product 和 product2 中售价高于 500 的商品的基本信息. select * from product wh...
datawhale组队学习task03