优化T-SQL提升SQL Server数据库性能

日期: 2015-01-07 作者:Basit Farooq翻译:冯昀晖 来源:TechTarget中国

数据库性能诊断不是一件容易的事,因为有很多种因素可能会导致瓶颈。糟糕的T-SQL代码是许多常见SQL Server数据库性能问题的根本原因,因为不管是直接使用还是通过API调用,核心数据库应用逻辑都使用了T-SQL语句。因此,优化T-SQL代码是调试SQL Server数据库应用性能潜在问题的最好方法。 下面列举了优化T-SQL代码,避免SQL Server数据库性能瓶颈的八个技巧。

不要使用DISTINCT和UNION语句 尽可能不要在T-SQL查询语句中使用DISTINCT和UNION语句。这两个关键词会极大地拖累查询性能,因为它们需要对查询结果执行排序操作来识别并去除重复数据记录。 在S……

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

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

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

微信公众号

TechTarget微信公众号二维码

TechTarget

官方微博

TechTarget中国官方微博二维码

TechTarget中国

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

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

数据库性能诊断不是一件容易的事,因为有很多种因素可能会导致瓶颈。糟糕的T-SQL代码是许多常见SQL Server数据库性能问题的根本原因,因为不管是直接使用还是通过API调用,核心数据库应用逻辑都使用了T-SQL语句。因此,优化T-SQL代码是调试SQL Server数据库应用性能潜在问题的最好方法。

下面列举了优化T-SQL代码,避免SQL Server数据库性能瓶颈的八个技巧。

不要使用DISTINCT和UNION语句

尽可能不要在T-SQL查询语句中使用DISTINCT和UNION语句。这两个关键词会极大地拖累查询性能,因为它们需要对查询结果执行排序操作来识别并去除重复数据记录。

在SELECT语句和INSERT语句中使用字段列表(不使用星号或者省略)

尽管字段列表参数对于“SELECT”和“INSERT”语句不是必须的,但是在写这类语句时写出完整的字段列表是有积极价值的。如果没有指定完整的字段清单,那么SQL Server在解析时会查询“SELECT”和“INSERT”语句的全部字段。另外,没有字段列表信息,在表结构变化的时候,这两种语句可能会产生错误。为了降低网络传输压力,改善“SELECT”查询的整体性能,建议在“SELECT”语句中使用准确的字段名称。

如果要使用复杂功能查询,请使用存储过程

如果可能的话,应该使用存储过程替代T-SQL复杂查询语句,因为存储过程中的代码是在单独的单元和批次执行的。这会极大地降低网络传输压力,因为存储过程中包含的许多T-SQL语句不需要通过网络多次分别传输。恰恰相反,只需要在网络中传输存储过程的名称及其参数。

SQL Server总是会缓存存储过程的执行计划,放在SQL Server专门内存区域中,即存储过程缓存区。只要有足够的内存可用,执行存储过程时也没有执行“WITH RECOMPILE”选项(强制重新编译),那么存储过程就总是会驻留在缓存区中被直接调用。在运行临时T-SQL语句时产生的临时SQL执行计划并不总是会存储在缓存区中。可见,SQL Server并不总是从磁盘提取和加载存储过程,也不会在每次运行时对存储过程做解析、优化和编辑。

使用TRUNCATE TABLE语句代替DELETE语句

如果要从表中删除所有行,一定要用“TRUNCATE TABLE”语句代替“DELETE”语句。“TRUNCATE TABLE”语句比不带条件的“DELETE”语句要快很多,因为它几乎不使用系统日志和数据库事务日志资源。与“DELETE”语句不同,我们使用“TRUNCATE TABLE”语句的时候,SQL Server不会对每一行数据单独记录删除日志。SQL Server只会对数据页反分配记录日志,按整体操作记录结果。

让事务尽可能小

同步运行几个大型事务会增加死锁的可能性,因此我们应该让事务尽可能短。我们应该尽量把较大的事务拆分成几个小事务,然后按批次执行它们。因为执行大型事务的时候,排他锁和更新锁会保持更长时间,所以如果大事务多了就会阻塞其他数据库行为,最终可能导致死锁。分批次执行大事务可以帮助使事务期间网络阻塞最小化,降低完成事务的延时,有利于锁的释放。

缩短事务时间

只要我们确保不要一遍一遍执行相同的读操作,就可以削减事务执行时间。如果你的应用需要多次读取相同的数据,那么你应该把数据缓存到变量、临时表或者表变量中。然后你就可以从缓存读取数据了。这样可以帮助降低对具体资源的锁占用时间。要减少锁占用时间,要确保应用获得锁的时机尽量晚,释放锁的时机尽量早。

尽可能避免使用游标

我们应该尽量避免使用游标。取而代之,我们应该使用基于成组的方法来从一个表向另一个表更新或者插入数据。在游标定义中应用到“SELECT”语句的锁规则会应用到其它“SELECT”语句。在使用游标时,要确保使用了正确的隔离级别,或者确保只对你的游标SELECT语句加锁。SQL Server会对游标中该SELECT语句和其中的独立“SELECT”语句保持锁状态,知道它们在事务中都执行完成。这种效果适用于SQL Server运行在显式事务或隐式事务模式的情况。

为表、存储过程和变量选择合适的数据类型

数据类型定义了数据存储到数据库表字段中的形式。在创建表的时候,你必须选择指定字段定义的数据类型。你还可以使用数据类型定义变量和存储过程输入输出参数。对于每个字段和变量,我们应该选择合适的数据类型存储数据。此外,应该考虑存储需求,选择有效率的存储数据类型。为表、存储过程和变量选择合适的数据类型还可以提高数据一致性,确保只有正确的数据类型才能存储到数据库中去。

作者

Basit Farooq
Basit Farooq

资深数据库管理员、培训师和技术撰稿人,具有十多年微软SQL Server平台的开发、技术培训和数据库管理的经验。

相关推荐