执行计划--在存储过程中使用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 ...
随机推荐
- Flask框架的学习与实战(一):开发环境搭建
Flask是一个使用 Python 编写的轻量级 Web 应用框架.其 WSGI 工具箱采用 Werkzeug ,模板引擎则使用 Jinja2.很多功能的实现都参考了django框架.由于项目需要,在 ...
- Getting Started(入门)
欢迎阅读专门针对android开发者的培训课程,在这一系列的课程中,描述了如何通过我们的示例代码来完成特定的任务和功能,这些代码可以灵活地应用到你的应用程序中. 课程被分成了几部分, 第一部分,入门, ...
- Linux Storage Stack Diagram存储堆栈图
这是一个描述非常好的存储栈,版本为:Linux Storage Stack Diagram v4.10,我在这里转载下图片,可以提升大家对存储栈的理解. https://www.thomas-kren ...
- 接口自动化(二)--操作Excel获取需要数据
这一部分的内容记述一下对Excel表格的操作,本实战中的测试用例是由Excel来管理的,因此操作Excel是重要的一部分. 再次贴出这张图,所有的测试用例都在这个sheet内,请求数据真实存放在jso ...
- 将mysql表数据批量导入redis zset结构中
工作中有这样一个需求,要将用户的魅力值数据做排行,生成榜单展示前40名,每隔5分钟刷新一次榜单.这样的需求用redis的zset是很方便实现的.但是数据存在mysql的表中,有400多万条,怎么将其快 ...
- 网络通信和TCP详解
交换机.路由器.服务器组网 1. 通信过程(pc+switch+router+server) 较为复杂的通信过程如:访问 www.baidu.com 注意:一定要配置 PC:IP.NETMASK.DF ...
- 【322】python控制键盘鼠标:pynput
参考:python实战===python控制键盘鼠标:pynput 参考:[Python Study Notes]pynput实现对鼠标控制 参考:pynput doc 参考:pynput Packa ...
- 2013年最后的收成:avalon1.0正式发布
大半年前我就说过,MVVM是前端究极的解决方案,因此之后我大多数时间都在折腾avalon,成立了专门的QQ群与感兴趣的一起讨论.感谢第一批吃螃蟹的人,avalon发展得很快,GITHUB上的贡献人数达 ...
- 若p是与10互质的质数,则p-1个9能被p整除
[若p是与10互质的质数,则k(p-1)个9能被p整除] 因为(p,10)=1,所以(p,10^k)=1.根据费马定理,10^(k*(p-1))-1|p. 而10^k*(p-1)-1是一个位数为(p- ...
- python's os.system&os.spawn
[python's os.system&os.spawn] os.system会新建一个子shell,在子shell中执行传入的sh脚本.os.spawn用于执行一个bin,产生一个子进程.所 ...