博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
执行计划--在存储过程中使用SET对执行计划的影响
阅读量:5064 次
发布时间:2019-06-12

本文共 1616 字,大约阅读时间需要 5 分钟。

--如果在存储过程中定义变量,并为变量SET赋值,该变量的值无法为执行计划提供参考(即执行计划不考虑该变量),将会出现预估行数和实际行数相差过大导致执行计划不优的情况

--如果在存储过程中使用SET为存储过程参数重新赋值,执行计划仍采用执行时传入的值来生成执行计划。
--=======================================
--准备测试数据
DROP TABLE TB1
GO
SELECT IDENTITY(INT,1,1) AS RID,
*INTO TB1
FROM sys.all_columns
GO
INSERT INTO TB1
SELECT *
FROM sys.all_columns
GO 100
ALTER TABLE TB1
ADD PRIMARY KEY(RID)
 
 
--测试查询参数使用变量
--例如下列存储过程,由于在生成执行计划时不知道@ID的具体值,因此无法预估满足PID>@ID条件的
CREATE PROCEDURE dbo.USP_GetData
(
  @PIDINT
)
AS
BEGIN
DECLARE @ID INT
SET @ID= @PID
SELECT *
FROM TB1
WHERE RID>@ID
END
GO
EXEC dbo.USP_GetData @PID=606808
--由于预估行数有问题,导致生成不使用索引的查询计划
 

--================================================= 

--测试修改传入参数的情况

--虽然传入参数在传入后被修改,但是生成执行计划时仍使用传入时的值
CREATE PROCEDURE dbo.USP_GetData2
(
  @PID INT
)
AS
BEGIN
SET @PID=@PID-606800
SELECT*
FROM TB1
WHERE RID>@PID
END
GO
EXEC dbo.USP_GetData2 @PID=606808

 

--================================================= 
--测试在查询时对传入参数做运算
CREATE PROCEDURE dbo.USP_GetData3
(
  @PID INT
)
AS
BEGIN
SELECT COUNT(1)
FROM TB1
WHERE RID>@PID+600080
END
GO
EXEC dbo.USP_GetData3 @PID=20
 

 --================================================= 

--测试在查询时对传入参数做运算(复杂运算)
----对应复杂运算,无法获得准确的值,因此不能准确地预估行数,也不能生成合理的执行计划
CREATE PROCEDURE dbo.USP_GetData4
(
  @PID INT
)
AS
BEGIN
SELECT COUNT(1)
FROM TB1
WHERE RID>@PID+CAST(RAND()*6000800 AS INT)
END
GO
EXEC dbo.USP_GetData4 @PID=20
GO

 

 

总结:

在存储过程中使用到的变量可以分为内部变量和外部变量
1>对于外部变量,存储过程编译时会使用该变量的真实值依据统计来生成执行计划,无论该外部变量是否在存储过程中发生修改
2>对于内部变量,存储过程编译时无法获取该变量的真实值,因此无法使用统计,从而只能生成"最通用"的执行计划(可能是比较差的执行计划)

补充:

可以使用OPTION(optimize for(@PID=75124))方式来解决因变量值导致的执行计划不优的问题

 

 

转载于:https://www.cnblogs.com/TeyGao/p/3527008.html

你可能感兴趣的文章
js跨域解决方式
查看>>
java对象是如何创建的
查看>>
7-1 抓老鼠啊~亏了还是赚了? (20 分)
查看>>
《Python编程从入门到实践》学习笔记8(第9章:类)
查看>>
Hibernate
查看>>
fedora 使用 vnc 远程 fedora 28 主机
查看>>
cocos2dx + vs安装使用
查看>>
CentOS 7下安装Logstash ELK Stack 日志管理系统(上)
查看>>
自然数e这家伙怎么蹦跶出来的?
查看>>
经常使用命令 echo、@、call、pause、rem
查看>>
PHP设计模式之适配器模式
查看>>
康托尔定理是如何证明的?
查看>>
Google Guice结合模式
查看>>
Linux centos 主机名颜色设置 和 别名设置
查看>>
jquery自己主动旋转的登录界面的背景代码登录页背景图
查看>>
(64位oracle使用32位的PLSQL)安装64位的oracle数据库软件,使用32位的PLSQL Developer连接方法...
查看>>
JavaScipt面向对象编程----闭包
查看>>
ajax异步通讯 遮罩滚动栏,防止并发及误操作
查看>>
Cocos2d-x项目移植到WP8小记
查看>>
如何在 Mac 上卸载 Java?
查看>>