[SQL Server 2005/2008]重用执行计划(存储过程性能优化)

 

源自《Microsoft SQL Server 2005技术内幕:T-SQL程序设计》7.4 编译、重新编译和重用执行计划

 

      语句或存储过程第1次执行时,会生成一个经时“查询优化器”优化后的执行计划,默认情况下,还将会缓存这次的执行计划; 下次执行时将直接使用缓存的执行计划,而且不检查这样做是否合适。 

 

-- 存在2个测试表: t_bak_20100520(inttime int, desc varchar(50)),inttime字段上建聚集索引,1000行数据;另外一个表t_bak_20100520_bak,和上面那个表结构和表数据,及索引完全一致。

 

-- 测试存储过程1(整个存储过程不缓存执行计划,每次执行时生成新的查询计划)

create proc p_test_detail1(@i_time int) with recompile

as

select * from dbo.t_bak_20100520 where inttime >= @i_time;

select * from dbo.t_bak_20100520_bak where inttime >= @i_time;

 

 go

-- 测试存储过程2(缓存存储过程中,第二个查询语句的计划,第一个语句每次都重新生成计划)

create proc p_test_detail2 (@i_time int)

as

select * from dbo.t_bak_20100520 where inttime >= @i_time option(recompile);

select * from dbo.t_bak_20100520_bak where inttime >= @i_time;

 go 

 

 ------ 测试内容和结果------------------------------------------------------------------------------------

SET STATISTICS IO   ON;   -- 查询结束后,显示io统计信息

SET STATISTICS TIME ON;   -- 查询结束后,显示cpu统计信息

exec p_test_detail1 145500

exec p_test_detail2 145500

 

exec p_test_detail1 700

exec p_test_detail2 700

 

 

(13 行受影响) 表't_bak_20100520'。        扫描计数 1,逻辑读取 15 次,...省略..       --生成查询计划是"索引扫描",不缓存查询计划
(13 行受影响) 表't_bak_20100520_bak'。扫描计数 1,逻辑读取 15 次,...省略同上.. --生成查询计划是"索引扫描",不缓存查询计划

(13 行受影响) 表't_bak_20100520'。        扫描计数 1,逻辑读取 15 次,...省略同上.. --生成查询计划是"索引扫描",不缓存查询计划
(13 行受影响) 表't_bak_20100520_bak'。扫描计数 1,逻辑读取 15 次,...省略同上.. --生成查询计划是"索引扫描",存查询计划


(595行受影响) 表't_bak_20100520'。        扫描计数 1,逻辑读取 740 次,...省略..    --生成查询计划是"表扫描"

(595行受影响) 表't_bak_20100520_bak'。扫描计数 1,逻辑读取 740 次,...省略..    --生成查询计划是"全表扫描"

(595行受影响) 表't_bak_20100520'。        扫描计数 1,逻辑读取 740 次,...省略..    --生成查询计划是"全表扫描"

(595行受影响) 表't_bak_20100520_bak'。扫描计数 1,逻辑读取 1121 次,...省略..    --缓存的查询计划"索引扫描"

 

  

       存储过程执行时,默认会缓存第一次执行时,最优的执行计划。以后再次执行该存储过程,则直接使用缓存中的执行计划。除非发现存储过程执行环境发生变化,要重新编译,并重新生成查询计划。(如引用的表结构变化了,索引变化了,SET选项(如ANSI_NULLS、CONCAT_NULL_ YIELDS_NULL等)变化了,或创建存储过程时,指定了要重新生成查询计划。“第一次执行”也包括因一定时间内没有重用或其他原因从缓存中移除计划之后的第一次执行。

 

  

-- 查询系统中缓存的执行计划

select cacheobjtype, objtype, usecounts, sql

from sys.syscacheobjects

where sql not like '%cache%'

and sql like '%p_test_detail%';

 

 

 

 

你可能感兴趣的:(sql,server,Microsoft,性能优化,存储,2010,statistics)