执行计划--在存储过程中使用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 ...
随机推荐
- 设置putty标题栏显示固定信息
设置好后,登录服务器后,发现标题栏又显示root@sit:/opt/ihome,没有显示成我设置的title内容.原因是: 在Terminal->Features中一定要勾选Disable re ...
- cmd,amd,umd 模块写法
mark一篇感觉写的不错的cmd/amd/umd的模块写法 原文:https://github.com/banricho/webLog/issues/12 umd通用写法: // jQuery 2.2 ...
- js解决弹窗问题实现班级跳转DIV示例
js解决弹窗问题实现班级跳转DIV 1.js代码如下: <%--实现班级跳转DIV--%> <div id="displayClassDiv" style=&q ...
- mybatis 需要注意的点 MyBatis 插入空值时,需要指定JdbcType (201
转自:https://blog.csdn.net/snakemoving/article/details/76052875 前天遇到一个问题 异常显示如下: 引用 Exception in threa ...
- Lrc歌词-开发标准
LRC歌词是在其程序当中实现的专门用于MP3等歌词同步显示的标签式的纯文本文件,如今已经得到了广泛的运用.现就LRC歌词文件的格式规定详细说明,已供程序开发人员参考. LRC文件是纯文本文件,可以用记 ...
- codeforces:855D Rowena Ravenclaw's Diadem分析和实现
题目大意: 提供n个对象,分别编号为1,...,n.每个对象都可能是某个编号小于自己的对象的特例或是成分.认为某个对象的特例的特例依旧是该对象的特例,即特例关系传递,同样一个对象的成分的成分依旧是该对 ...
- SSD
https://blog.csdn.net/WZZ18191171661/article/details/79444217 论文题目:SSD: Single Shot MultiBox Detecto ...
- ICG游戏:斐波那契博弈
描述: 有一堆个数为n(n>=2)的石子,游戏双方轮流取石子,规则如下: 1)先手不能在第一次把所有的石子取完,至少取1颗: 2)之后每次可以取的石子数至少为1,至多为对手刚取的石子数的2倍: ...
- 8-matlab-gui-显示图片有坐标刻度问题
在图片上显示图片时,总是有图片,一遍做法是使得刻度为空就可了: 在你的每一个axes的CreateFcn函数中添加一下代码即可:set(hObject,'xTick',[]);set(hObject, ...
- SVG DOM常用属性和方法介绍(1)
12.2 SVG DOM常用属性和方法介绍 将以Adobe SVG Viewer提供的属性和方法为准,因为不同解析器对JavaScript以及相关的属性和方法支持的程度不同,有些方法和属性是某个解析 ...