执行计划--在存储过程中使用SET对执行计划的影响
--如果在存储过程中定义变量,并为变量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))方式来解决因变量值导致的执行计划不优的问题
执行计划--在存储过程中使用SET对执行计划的影响的更多相关文章
- oracle存储过程中使用execute immediate执行sql报ora-01031权限不足的问题
oracle存储过程中使用execute immediate执行sql报ora-01031权限不足的问题 学习了:http://blog.csdn.net/royzhang7/article/deta ...
- 存储过程中拼写sql并执行
直接上代码吧,根据不同的条件拼写sql后并执行 ALTER PROCEDURE [dbo].[usp_Statistic_WJB_DZSK_ZT] ( @year int, @half int,--0 ...
- 【oracle】存储过程中获取delete语句执行后删除的记录数
dbms_output.put_line(to_char(sql%rowcount));
- 存储过程中使用事务,sql server 事务,sql事务
一.存储过程中使用事务的简单语法 在存储过程中使用事务时非常重要的,使用数据可以保持数据的关联完整性,在Sql server存储过程中使用事务也很简单,用一个例子来说明它的语法格式: 代码 ...
- mysql-存储过程案例-存储过程中创建表和修改表数据
-- 本存储过程有特殊执行循环数量的要求,是对security_market_history表进行修正 -- 判断存储过程是否存在 drop PROCEDURE if exists proc_secu ...
- MySQL存储过程中的3种循环
在MySQL存储过程的语句中有三个标准的循环方式:WHILE循环,LOOP循环以及REPEAT循环.还有一种非标准的循环方式:GOTO,不过这种循环方式最好别用,很容易引起程序的混乱,在这里就不错具体 ...
- 存储过程中使用事务与try catch
一.存储过程中使用事务的简单语法 在存储过程中使用事务时非常重要的,使用数据可以保持数据的关联完整性,在Sql server存储过程中使用事务也很简单,用一个例子来说明它的语法格式: 代码 : ) ) ...
- MySQL存储过程中的3种循环【转载】
在MySQL存储过程的语句中有三个标准的循环方式:WHILE循环,LOOP循环以及REPEAT循环.还有一种非标准的循环方式:GOTO,不过这种循环方式最好别用,很容易引起程序的混乱,在这里就不错具体 ...
- 存储过程中使用事务和try catch
一.存储过程中使用事务的简单语法 在存储过程中使用事务时非常重要的,使用数据可以保持数据的关联完整性,在Sql server存储过程中使用事务也很简单,用一个例子来说明它的语法格式: 代码 : Cre ...
随机推荐
- Centos生成SSL证书的步骤
1.yum install openssl安装openssl组件2.生成KEY的流程步骤如下 1. 创建根证书密钥文件(自己做CA)root.key: openssl genrsa -out root ...
- Oracle VM VirtualBox安裝Windows 2000失败
问题: VirtualBox下安装Windows2000,设置网络后进入最后一步,复制组件……然后就是重启:再试还是重启! 解决: 在Oracle网站上查了一下资料:http://www.virt ...
- PMP Fundamentals
- J.U.C 整体认识
深入浅出 Java Concurrency (1) : J.U.C的整体认识 去年年底有一个Guice的研究计划,可惜由于工作“繁忙”加上实际工作中没有用上导致“无疾而终”,最终只是完成了Guice的 ...
- leetcode374
// Forward declaration of guess API. // @param num, your guess // @return -1 if my number is lower, ...
- 7.25 11figting!
TEXT 76 Start of the long march 而今迈步从头越(陈继龙编译) Nov 16th 2006 | BEIJING AND HONG KONG From The Econom ...
- sass对象的定义
sass在3.3引入map类型,它与JS的对象非常相似,它有两种定义模式.外面都是用小括号括括起来,每个键值对可以像JS那样与逗号分开.不同之后是,键名与键值之间的冒号不是 必须的 不用对象的情况 @ ...
- CCS5配置使用GenCodecPkg生成CODEC SERVER
1. 引言 CCS5中集成了算法生成工具的插件,使用XDAIS Tools条目里面的GenAlg命令生成的算法框架如下: 不过,我没找到如何在CCS中使用这个工程.难不成要把这个框架文件放在Linux ...
- What I'm Researching
[What I'm Researching] 1.C++11 2.NLP 3.android dev 4.warm up 5.PageRank
- 在Spring使用junit注解进行单元测试
在Spring中可以使用junit配合注解进行单元测试 一.常用注解 1.@RunWith(SpringJUnit4ClassRunner.class),让测试运行于spring测试环境2.@Cont ...