频 道 直 达 - 新闻 - 培训 - 软件 - 教程 - 前沿 - 组网 - 系统应用 - 安全 - 编程 - 存储 - 操作系统 - 数据库 - 服务器 - 专题 - 产品 - 案例库 - 读书 - 博客 - BBS
51CTO.COM_中国最大的网络技术网站
找资料:

7.4.2 重新编译

作者: (美)Itzik Ben-gan... 赵立东译 出处:电子工业出版社博文视点  2007-10-23 17:52    砖    好    评论   进入论坛
阅读提示:《Microsoft SQL Server 2005技术内幕:T-SQL程序设计》第7章首先简要介绍SQL Server 2005所支持的不同类型的存储过程,然后再深入研究它的细节。本文是重新编译。

重新编译

我前面曾提到过,默认情况下存储过程会重用之前缓存的执行计划。但也有一些例外会导致重新编译。在SQL Server 2000中,重新编译发生在整个存储过程级别上,而在SQL Server 2005中,它可以发生于语句级别上。
与计划正确性(plan correctness)和计划最优性(plan optimality)相关的问题可能会导致这种情况。计划正确性问题包括基对象的架构更改(例如,添加/删除列、添加/删除索引等)或更改可以影响查询结果的SET选项(例如,ANSI_NULLS、CONCAT_NULL_ YIELDS_NULL等)。导致重新编译的计划最优性问题包括更改被引用对象的数据到一定程度,以致于使用新计划可能会更合适。例如,由于更新统计信息。

导致重新编译的两种原因有许多特例。在本节的最后,我将为你提供一个更为详细描述它们的资源。
当然,如果计划在一段时间内没有重用而被移出缓存,再次调用该存储过程时SQL Server将生成一个新的计划。
来看一个导致重新编译例子,运行下面的代码,它创建存储过程usp_CustCities。

IF OBJECT_ID('dbo.usp_CustCities') IS NOT NULL
DROP PROC dbo.usp_CustCities;
GO

CREATE PROC dbo.usp_CustCities
AS

SELECT CustomerID, Country, Region, City,
Country + '.' + Region + '.' + City AS CRC
FROM dbo.Customers
ORDER BY Country, Region, City;
GO

该存储过程查询Customers表,并串联消费者三个物理位置:Country、Region和City。SET选项CONCAT_NULL_YIELDS_NULL默认为ON,表示当你用任意字符串和NULL串联时,得到的结果都为NULL。
第一次运行存储过程,你会得到表7-7所示的输出(被简化)。

CustomerID

Country

Region

City

CRC

CACTU

Argentina

NULL

Buenos Aires

NULL

OCEAN

Argentina

NULL

Buenos Aires

NULL

RANCH

Argentina

NULL

Buenos Aires

NULL

ERNSH

Austria

NULL

Graz

NULL

PICCO

Austria

NULL

Salzburg

NULL

MAISD

Belgium

NULL

Bruxelles

NULL

SUPRD

Belgium

NULL

Charleroi

NULL

QUEDE

Brazil

RJ

Rio de Janeiro

Brazil.RJ.Rio de Janeiro

RICAR

Brazil

RJ

Rio de Janeiro

Brazil.RJ.Rio de Janeiro

HANAR

Brazil

RJ

Rio de Janeiro

Brazil.RJ.Rio de Janeiro

GOURL

Brazil

SP

Campinas

Brazil.SP.Campinas

WELLI

Brazil

SP

Resende

Brazil.SP.Resende

TRADH

Brazil

SP

Sao Paulo

Brazil.SP.Sao Paulo

FAMIA

Brazil

SP

Sao Paulo

Brazil.SP.Sao Paulo

COMMI

Brazil

SP

Sao Paulo

Brazil.SP.Sao Paulo

如你所见,只要Region为NULL,串联后的字符串则为NULL。SQL Server缓存了存储过程的执行计划以备日后重用。除了执行计划,SQL Server还会存储所有可以影响查询结果的SET选项。你可以在sys.syscacheobjects的setopts位图中观察到这一点。
设置CONCAT_NULL_YIELDS_NULL选项为OFF,通知SQL Server在串联时把NULL当作空字符串处理。

SET CONCAT_NULL_YIELDS_NULL OFF

重新运行这个存储过程,将生成表7-8所显示的输出(被简化)。

EXEC dbo.usp_CustCities;

表7-8  CONCAT_NULL_YIELDS_NULL为OFF时usp_CustCities 的输出(被简化)

CustomerID

Country

Region

City

CRC

CACTU

Argentina

NULL

Buenos Aires

ArgentinaBuenos Aires

OCEAN

Argentina

NULL

Buenos Aires

ArgentinaBuenos Aires

RANCH

Argentina

NULL

Buenos Aires

ArgentinaBuenos Aires

ERNSH

Austria

NULL

Graz

AustriaGraz

PICCO

Austria

NULL

Salzburg

AustriaSalzburg

MAISD

Belgium

NULL

Bruxelles

BelgiumBruxelles

SUPRD

Belgium

NULL

Charleroi

BelgiumCharleroi

QUEDE

Brazil

RJ

Rio de Janeiro

Brazil.RJ.Rio de Janeiro

RICAR

Brazil

RJ

Rio de Janeiro

Brazil.RJ.Rio de Janeiro

HANAR

Brazil

RJ

Rio de Janeiro

Brazil.RJ.Rio de Janeiro

GOURL

Brazil

SP

Campinas

Brazil.SP.Campinas

WELLI

Brazil

SP

Resende

Brazil.SP.Resende

TRADH

Brazil

SP

Sao Paulo

Brazil.SP.Sao Paulo

FAMIA

Brazil

SP

Sao Paulo

Brazil.SP.Sao Paulo

COMMI

Brazil

SP

Sao Paulo

Brazil.SP.Sao Paulo

你可以看到,当Region为NULL,它被当作空字符串来处理,这样,CRC列就不会包含NULL了。在这个例子中,更改会话选项会改变查询的意义。运行这个存储过程时,SQL Server首先检查是否存在缓存的计划,且该计划所包含的状态与当前SET选项是否相同。SQL Server没发现这样的计划 ,所以它生成一个新的计划。注意,不论对SET选项的更改是否真的影响了查询的意义,SQL Server都会查询匹配的SET选项状态再重用计划。
查询sys.syscacheobjects,你会找到usp_CustCities的两个计划,并包含两个不同的setopts位图,如表7-9所示。

SELECT cacheobjtype, objtype, usecounts, setopts, sql
FROM sys.syscacheobjects
WHERE sql NOT LIKE '%cache%'
AND sql LIKE '%usp_CustCities%';


表7-9  sys.syscacheobjects 中usp_CustCities的执行计划

cacheobjtype

objtype

usecounts

setopts

sql

Compiled Plan

Proc

1

4347

CREATE PROC dbo.usp_CustCities

Compiled Plan

Proc

1

4339

CREATE PROC dbo.usp_CustCities

当建立数据库连接时,客户端接口和工具通常会更改一些SET选项的状态。不同的客户端接口更改不同的SET选项,形成不同的执行环境。如果使用多个数据库接口和工具连接到数据库,而且它们拥有不同的执行环境,你将无法重用其他应用程序的计划。在应用程序连接到数据库时,通过运行一个跟踪,你可以很容易地识别出客户端工具更改的SET选项。如果发现执行环境有差异,你可以在所有的应用程序中显式地设置SET命令,并在建立连接时提交。通过这种方法,所有的应用程序都将拥有一致的执行环境并重用其他应用程序的计划。
实验完成后,把CONCAT_NULL_YIELDS_NULL选项改回ON:

SET CONCAT_NULL_YIELDS_NULL ON;

这只是不重用执行计划的情况之一,还有很多这种情况。下面这一节的最后,我会提供一些资源,通过这些资源你可以找到更多的信息。

【责任编辑:雪花 TEL:(010)68476606-8007】

回书目   上一节   下一节
专题
存储为核心的系统发展之路
虚拟存储企业级应用座谈会
网络存储导论
SAN存储技术
网络存储入门——光纤通道
我也说两句

匿名发表

(如果看不清请点击图片进行更换)


中 国 最 大 的 网 络 技 术 网 站 ·
技 术 成 就 梦 想
订阅技术快讯