SQL Server中使用游标进行行处理

日期: 2009-08-10 作者:Baya Pavliashvili翻译:曾少宁 来源:TechTarget中国 英文

当应用程序用户开始遇到性能问题时,一般他们会联系数据库管理员并询问是否数据库存在问题。有趣的是,大多数用户都会查看内存、CPU和磁盘使用率,而不是造成严重性能问题的特定的代码模块;很不幸,导致严重性能问题的往往是编写不当的Transact-SQL (T-SQL)代码;而且,通过在服务器上增加更多的内存来解决这些问题,而不对问题的根源进行修复,将直接导致更大的问题。因此,你必须找出确定性能糟糕的查询并对它们进行优化。   T-SQL是一个强大的程序语言,它可以读取和修改数据、改变SQL Server设置、创建和修改数据库对象、修改Registry设置等等。

然而,必须谨记的是,没有任何一个T-SQ……

我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。

我原创,你原创,我们的内容世界才会更加精彩!

【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】

微信公众号

TechTarget微信公众号二维码

TechTarget

官方微博

TechTarget中国官方微博二维码

TechTarget中国

电子邮件地址不会被公开。 必填项已用*标注

敬请读者发表评论,本站保留删除与本文无关和不雅评论的权力。

当应用程序用户开始遇到性能问题时,一般他们会联系数据库管理员并询问是否数据库存在问题。有趣的是,大多数用户都会查看内存、CPU和磁盘使用率,而不是造成严重性能问题的特定的代码模块;很不幸,导致严重性能问题的往往是编写不当的Transact-SQL (T-SQL)代码;而且,通过在服务器上增加更多的内存来解决这些问题,而不对问题的根源进行修复,将直接导致更大的问题。因此,你必须找出确定性能糟糕的查询并对它们进行优化。

  T-SQL是一个强大的程序语言,它可以读取和修改数据、改变SQL Server设置、创建和修改数据库对象、修改Registry设置等等。然而,必须谨记的是,没有任何一个T-SQL功能可以适应所有环境和所有应用的。比如,如果你的应用需要在不同网络共享中复制大量的文件,那么T-SQL就不是你的最佳选择了。类似的,使用SQL Server的内置电子邮件功能来发送多兆字节附件的电子邮件并不是一个好主意。相反,如果你需要在数据库中检索数据行或者修改所有满足特定条件的行,那么T-SQL则是你的最佳选择。由于T-SQL支持大量的功能,因此我无法全面的阐述可能造成性能问题的所有具体情况。相反,我将介绍某些情况下一种编写代码的方法将可以改善其它方面的性能。

  使用游标进行行处理

  游标可能是最常见的引起性能问题的原因,虽然它们对于某些任务而言是一个强大且方便的方法。比如,假设你有一个复杂的存储过程,其中你必须反复调用存储在临时表中的每一行数据。你可以使用光标从临时表中检索参数值,同时对每一个检索的值都调用一次存储过程。基本上,游标允许你处理数据集中的每一行数据,同时对数据记录进行相同的逻辑处理,每次处理一行数据。然而,T-SQL是一个基于集合的语言;这种语言是针对记录集进行数据读写操作优化的,而不是针对记录行。从前端特定语言(比如VBScript、ASP或者ColdFusion)开发转变过来的T-SQL初学者,他们往往在并不需要循环时在T-SQL中错误地使用循环。比如,下面的代码将酒店数据库的所有California作者的“姓”标记为“changed”:

  DECLARE @last_name VARCHAR(50),
  @au_id CHAR(11)
  DECLARE last_name_cursor CURSOR FOR
  SELECT au_id, au_lname FROM authors
  WHERE state = 'ca'
  OPEN last_name_cursor
  FETCH NEXT FROM last_name_cursor INTO @au_id, @last_name
  WHILE @@FETCH_STATUS = 0
  BEGIN
  UPDATE authors
  SET au_lname = @last_name + ' changed'
  WHERE au_id = @au_id
  FETCH NEXT FROM last_name_cursor INTO @au_id, @last_name
  END
  CLOSE last_name_cursor
  DEALLOCATE last_name_cursor
  这段代码是可以运行的,因为只有少量California作者,因此它很快就完成运行。现在让我们来看看我们是否可用简单的更新语句来重写相同的逻辑:

  UPDATE authors
  SET au_lname = @last_name + ' changed'
  WHERE state = 'ca'

  应该怎么做呢?事实上,两段代码都完成了相同的任务,但是第二段代码不仅更加简单,而且它在大数据集中运行的速度大约比第一段代码快100倍。我曾经在过去的几个项目将游标使用方法改变为基于数据集的方法,从而将查询的持续时间从几个小时减少为不到一分钟。

翻译

曾少宁
曾少宁

TechTarget中国特约技术编辑,某高校计算机科学专业教师和网络实验室负责人,曾任职某网络国际厂商,关注数据中心、开发运维、数据库及软件开发技术。有多本关于思科数据中心和虚拟化技术的译著,如《思科绿色数据中心建设与管理》和《基于IP的能源管理》等。

相关推荐