此博客介绍了简单但有用的提示和优化,以提高存储过程的性能。

0.with recompile:重编译

  exec uspGetSalesInfoForDateRange ‘1/1/2009’, 31/12/2009 with recompile

1.使用SET NOCOUNT ON

  SQL Server在运行select或DML操作时返回信息性消息。如果一个过程有许多这样的语句,游标或while循环SQL Server将显示许多此类消息,增加网络流量。可以使用SET NOCOUNT ON来抑制这些消息,并可以通过减少网络流量来提高性能。

2.使用完全限定的程序名称

  完全限定的对象名称是database.schema.objectname。当存储过程作为schemaname.procedurename调用时,SQL Server可以快速查找已编译的计划,而不是在未指定schemaname时查找其他模式中的过程。这可能不会对性能产生很大的推动作用,但应该遵循最佳实践。过程中的所有对象也应该称为schemaname.objectname。

3. sp_executesql而不是Execute用于动态查询

  sp_executesql允许重用缓存计划并防止SQL注入。我们来看一个计划重用的例子。

 
1
2
3
4
5
6
7
8
9
10
DBCC FREEPROCCACHE
GO
Declare
@dynamic_sql varchar(max),
@salesorderid int
SET @salesorderid=43660
 
SET @dynamic_sql=' SELECT * FROM Sales.SalesOrderDetail where SalesOrderID='
+ CAST(@salesorderid AS VARCHAR(100))
EXECUTE(@dynamic_sql)

上面的查询使用EXECUTE命令为salesorderid 43660和43661的两个值执行动态查询。让我们分析缓存的计划。

  如上面的快照所示,两个salesorderids有两个单独的计划。现在让我们使用sp_execute SQL执行相同的查询并分析缓存的计划。

 
1
2
3
DECLARE @dynamic_sql NVARCHAR(100)
SET @dynamic_sql = N'SELECT * FROM Sales.SalesOrderDetail where SalesOrderID=@salesorderid'
EXECUTE sp_executesql @dynamic_sql, N'@salesorderid int', @salesorderid = 43661

  上面的查询使用sp_executesql为2个不同的salesorderid值执行动态查询。我们来分析一下缓存的计划。

  如上面的快照所示,只缓存了一个计划,并用于salesorderid的不同值。

4.使用IF EXISTS AND SELECT

  IF EXISTS用于检查记录,对象等的存在。并且是一个方便的语句,用于提高查询的性能,其中一个只想检查表中记录的存在而不是在查询中使用该记录/行。这样做的时候使用IF EXISTS(来自mytable的SELECT 1)而不是IF EXISTS(从mytable中选择*),因为我们感兴趣的只是检查记录/ s的存在。因此,如果查询返回1,则记录存在,否则不存在。无需返回所有列值。

5.避免将用户存储过程命名为sp_procedurename。

  如果存储过程以sp_开头,则SQL Server首先在master数据库中搜索它,然后在当前用户数据库中搜索它。这可能会导致轻微的性能问题,而且如果master数据库中存在具有相同名称的存储过程,则可能导致错误的结果。

6.尽可能使用基于集合的查询。

  T-SQL是一种基于集合的语言,因此循环在这里不能很好地工作。仅当基于集合的查询要么昂贵或无法制定时,才使用游标和while循环。

7.保持交易简短明快

  事务越长,根据隔离级别保持锁定的时间越长。这可能会导致死锁和阻塞。打开一个新的查询窗口并执行以下查询

 
1
2
3
4
5
6
use AdventureWorks2014
GO
BEGIN TRANSACTION
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
 
SELECT * FROM Sales.SalesOrderDetail

请注意查询的会话ID。打开一个新的查询窗口并执行以下查询。记下查询的会话ID。

 
1
2
3
begin tran
Update Sales.SalesOrderDetail
SET OrderQty=50 WHERE SalesOrderDetailID=1

以上更新查询将等待共享锁上的选择查询。让我们分析这两个会话的锁。

  

如上面的快照所示,会话58更新查询正在等待会话57采取的共享锁。

请遵循这些提示,让我知道它如何提高程序性能。将返回一些更多提示和最佳实践。

最新文章

  1. NSPredicate 的使用
  2. 算法(第4版)-1.5 案例研究:union-find算法
  3. redis 初探
  4. Program C 暴力求解
  5. eclipse 中创建maven web项目
  6. QT中静态库的生成与使用——创建共享库代码,附例子
  7. Linux 经典电子书共享下载
  8. RESTful API接口文档规范小坑
  9. 在命令行启动vscode
  10. Keras学习率调整
  11. Quest for sane signals in Qt - step 1 (hand coding a Q_OBJECT)
  12. 配置Codis-Service主机
  13. RedHat 6.4 安装WAS 7.0 启动失败com.ibm.websphere.ssl.SSLException
  14. Netty核心概念(6)之Handler
  15. C语言 · 用宏求球的体积
  16. VHD和VHDX
  17. Spring ListFactoryBean实例
  18. Rails中文乱码问题【转】
  19. 重复造轮子系列--字符串处理(C语言)
  20. LeetCode OJ-- Linked List Cycle II **

热门文章

  1. java-信息安全(十五)-单向认证
  2. 二叉树转换成森林&森林变成二叉树
  3. (转) at&T语法格式 与 at&T - intel格式对比
  4. AbtestingGateway 复制请求到其他服务上
  5. [UFLDL] Generative Model
  6. svn eclipse链接
  7. linux如何查看某个端口是否开放
  8. A - 小希的迷宫
  9. AngularJS基础02 神奇的数据绑定(Binding)
  10. Book118免费下载文档方法