提高性能——存储过程最佳实践

原文地址:http://msdn.microsoft.com/en-us/library/ms187926.aspx 

 

  • Use the SET NOCOUNT ON statement as the first statement in the body of the procedure. That is, place it just after the AS keyword. This turns off messages that SQL Server sends back to the client after any SELECT, INSERT, UPDATE, MERGE, and DELETE statements are executed. Overall performance of the database and application is improved by eliminating this unnecessary network overhead. For information, see SET NOCOUNT (Transact-SQL).

使用NOCOUNT开关提高性能。在CREATE PROCEDURE <procedure_name> AS 后加入“SET NOCOUNT ON” 语句可以减少发送额外的信息,从而减少网络传输开销。具体说来这个开关会让SQL SERVER在把SELECT, INSERT, UPDATE, MERGE, and DELETE 等语句的执行结果返回给客户端后,停止发送额外的消息。
  • Use schema names when creating or referencing database objects in the procedure. It will take less processing time for the Database Engine to resolve object names if it does not have to search multiple schemas. It will also prevent permission and access problems caused by a user’s default schema being assigned when objects are created without specifying the schema. For more information, see User-Schema Separation.

当引用一个数据库对象时,指明schema name,这样可以免去DB engine解析该数据库对象时查找schema的时间。举例说,就是使用myDatabase.dbo.myTable, 而不是myDatabase..myTable (这里dbo可以按需替换成其他的schema)。指明schema的另一个好处是,当创建新的数据库对象时,不会把用户自身的schema作为默认schema赋给新对象 (很多时候,用户如果没意识到的话,可能会带来麻烦)。
  • Avoid wrapping functions around columns specified in the WHERE and JOIN clauses. Doing so makes the columns non-deterministic and prevents the query processor from using indexes.

不要对WHERE或者JOIN语句里的column使用函数,因为这样会使查询处理器无法使用索引来提高性能。
  • Avoid using scalar functions in SELECT statements that return many rows of data. Because the scalar function must be applied to every row, the resulting behavior is like row-based processing and degrades performance.

当查询返回大量结果时,避免在SELECT语句里使用标量函数 (返回单值的函数),如MID(), LEN(), ROUND(), FORMAT()等。因为这些函数会在每一行返回的结果上执行,因此会很大程度上影响性能。
  • Avoid the use of SELECT *. Instead, specify the required column names. This can prevent some Database Engine errors that stop procedure execution. For example, a SELECT * statement that returns data from a 12 column table and then inserts that data into a 12 column temporary table will succeed until the number or order of columns in either table is changed.

避免使用SELECT *, 指明每一个需要返回的列的名字。因为如果使用SELECT*的话,在语句执行过程中,列的个数或顺序发生任何改变的话,语句执行就会出错停止。
  • Avoid processing or returning too much data. Narrow the results as early as possible in the procedure code so that any subsequent operations performed by the procedure are done using the smallest data set possible. Also, sending just the essential data to the client application is more efficient than sending extra data across the network and forcing the client application to work through unnecessarily large result sets.

避免处理和返回过多的数据。尽量使后续操作在尽可能小的结果集上进行。同时,返回尽量小的结果集给客户端也可以大大的减少网路传输开销。
使用显式事务( 用BEGIN/END TRANSACTION声明的事务, 另参见 Implicit Transactions),并保证事务尽可能的短,以避免死锁。
  • Avoid using a wildcard as the leading character in a LIKE clause, for example, LIKE ‘%a%’. Because the first character is non-deterministic, the query processor is unable to use available indexes. Use LIKE ‘a%’ instead.

不要在LIKE语句里使用通配符%开始的字串。因为如果第一个字符不确定的话,查询引擎就没法使用索引。
  • Use the Transact-SQL TRY…CATCH feature for error handling inside a procedure. TRY…CATCH can encapsulate an entire block of Transact-SQL statements. This not only creates less performance overhead, it also makes error reporting more accurate with significantly less programming. For more information, see Using TRY...CATCH in Transact-SQL.

使用TRY...CATCH封装代码段来处理错误,一来可以减少performance损失,二来可以使错误报告更精确,并且相比其他方式,这种做法需要的代码量少得多。
  • Use the DEFAULT keyword on all table columns that are referenced by CREATE TABLE or ALTER TABLE Transact-SQL statements in the body of the procedure. This will prevent passing NULL to columns that do not allow null values.

当创建或更改一个表时,在所有用到的column上应用DEFAULT关键字。因为如果有默认值的话,可以避免给非空的column传递空值。
  • Use NULL or NOT NULL for each column in a temporary table. The ANSI_DFLT_ON and ANSI_DFLT_OFF options control the way the Database Engine assigns the NULL or NOT NULL attributes to columns when these attributes are not specified in a CREATE TABLE or ALTER TABLE statement. If a connection executes a procedure with different settings for these options than the connection that created the procedure, the columns of the table created for the second connection can have different nullability and exhibit different behavior. If NULL or NOT NULL is explicitly stated for each column, the temporary tables are created by using the same nullability for all connections that execute the procedure.

为所有临时表里的列指明空或非空。因为,如果不指明的话,空或非空是根据ANSI_DFLT_ON和ANSI_DFLT_OFF这两个开关来制定的,而不同的连接可能有不同的上下文,所以可能出现同一个存储过程在不同的连接下,其临时表的列非空约束不一致。 (关于临时表可参见 这里 ,temporary table部分)
  • Use modification statements that convert nulls and include logic that eliminates rows with null values from queries. Be aware that in Transact-SQL, NULL is not an empty or “nothing” value. It is a placeholder for an unknown value and can cause unexpected behavior, especially when querying for result sets or using AGGREGATE functions. For more information, see NULL Comparison Search Conditions and Null Values.

尽量将结果里的空值转换为有意义的值。因为在T-SQL里,空值并不代表空或没有,它代表的是unknow (当跟它做比较时返回的既不是true,也不是false),所以可能带来一些不可预期的行为,尤其当使用聚集函数时。
  • Use the UNION ALL operator instead of the UNION or OR operators, unless there is a specific need for distinct values. The UNION ALL operator requires less processing overhead because duplicates are not filtered out of the result set.

如果能使用UNION ALL操作就不要用UNION或者OR,因为UNION ALL可以自动剔除重复的结果,从而减少不必要的处理负担。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
存储过程的安全及性能优化 存储过程分类  系统存储过程  自定义存储过程  SQL Server使用者编写的存储过程  扩展存储过程  动态链接库(DLL)函数的调用看,主要用于客户端和服务器端之间进行通信  exec master..xp_cmdshell 'dir *.exe' -- 执行目录命令查询[sql2005\sql2008]  exec master..xp_fixeddrives --列出硬盘分区各自可用空间  xp_regwrite根键,子键,值名,值类型,值【sql2008拒绝访问】  写入注册表,例如:  exec master..db.xp_regwrite 'HKEY_LOCAL_MACHINE','SOFTWARE\Microsoft\Windows\CurrentVersion\run','TestValueName','reg_sz','hello'  xp_regdeletevalue 根键,子键,值名【sql2008拒绝访问】  删除注册表某个值  xp_regdeletekey键,值【sql2008拒绝访问】  删除该键下包括的所有值 xp_cmdshell语法  xp_cmdshell {'command_string'} [,no_output]  command_string是在操作系统命令行解释器上执行的命令字符串。command_string数据类型为varchar(255)或者nvarchar(4000),没有默认值  no_output为可选参数,可以控制是否想客户端返回信息  该存储过程一般情况下被禁用的,需要手动开启使用,如下:  exec sp_configure 'show advanced options',1  go   reconfigure  go   exec sp_configure 'xp_cmdshell',1—1表示启用,0表示禁用  go   reconfigure  go 删除xp_cmdshell SQL SERVER200删除xp_cmdshell use master exec sp_dropextendedproc 'xp_cmdshell' go SQL SERVER2005以上禁用xp_cmdshell,但不能删除掉 exec sp_configure 'xp_cmdshell',0 —1表示启用,0表示禁用  go reconfigure --让sp_configurre立即生效  go  exec sp_configure 'show advanced options',0  go   reconfigure  go --注意:SQL SERVER2008考虑安全性很多存储过程直接被拒绝访问 恢复/启用扩展存储过程 SQLServer2000 use master exec sp_addextendedproc xp_cmdshell,'xplog70.dll' go SQL Server2005或SQL Server2008启用xp_cmdshell  exec sp_configure 'show advanced options',1  go   reconfigure  go   exec sp_configure 'xp_cmdshell',1—1表示启用,0表示禁用  go   reconfigure  go 扩展存储过程的定义  扩展存储过程是SQL Server中的另一类存储过程,它是以其它语言编写的外部程序,是以动态链接库(DLL)形式存储在服务器上,最终SQLServer就可以动态加载并执行它们  编写好后使用SQLServer的固定角色sysadmin注册该扩展存储过程,并将执行权限授予其它用户,这个扩展存储过程只能添加到master数据库。  在编写扩展存储过程中可能要用到某些系统存储过程,这些系统存储过程如下: 利用OLE自动化存储过程调用dll 1.创建类库程序集 namespace PB_ExtendProcedure { public class ExtendProcedure { public string SayHi() { return "hello world"; } } } 2.生成动态链接库并注册到系统中 2.1.生成动态链接库使用VS2010命令行工具 使用sn命令生成一个强命名文件: sn -k he

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值