当前位置: 首页 > 编程日记 > 正文

《Microsoft Sql server 2008 Internals》读书笔记--第九章Plan Caching and Recompilation(10)

《Microsoft Sql server 2008 Internals》读书笔记订阅地址:

http://www.cnblogs.com/downmoon/category/230397.html/rss

《Microsoft Sql server 2008 Internals》索引目录:

《Microsoft Sql server 2008 Internal》读书笔记--目录索引

上文主要介绍计划缓存的时机和计划缓存冲突。本文将继续关注计划指南(Plan Guide)和优化指示(Optimization Hints),由于篇幅所限,计划指南分两部分,第一部分包括:优化提示、计划指南的意图、计划指南的类型。第二部分包括:计划指南的管理、计划指南的考虑因素、计划指南的有效性、从计划缓存中冻结计划。本文是第一部分。

优化提示(Optimization Hints)

ReCompile   Recompile提示强制SQL Server重新编译一个计划。这在一个批处理中仅仅一个语句时特别有用。SQL Server编译T-SQL批处理为一个Unit,为批处理中的每个语句决定执行计划,直到整个批处理被编译之前,它不会执行任何语句。这意味着如果批处理中包含变量声明和赋值,但赋值在编译阶段并没有实际发生。当下列批处理被优化时,SQL Server并没有为变量定义一个值:

USE Northwind2;
DECLARE @custID nchar(10);
SET @custID = 'LAZYK';
SELECT * FROM Orders WHERE CustomerID = @custID;

这个针对select语句的计划将表明SQL Server正在扫描完整的聚集索引。因为在优化期间,SQL Server并不知道什么值将被搜索,不能使用索引统计的直方图得到一个好的行数的估算。如果我们用常量LAZYK取代变量,SQL Server能决定仅仅有数行将被修饰,将有选择地使用CustomID上的非聚集索引。Recompile Hint此时非常有用,因为它告诉优化器在语句被执行前准备一个针对单个select语句的新计划。在Set选项后语句执行:

USE Northwind2;
DECLARE @custID nchar(10);
SET @custID = 'LAZYK';
SELECT * FROM Orders WHERE CustomerID = @custID
OPTION (RECOMPILE);

注意:一个变量并不同于一个参数,即使他们用同样的方式被写。因为过程仅在被执行时编译。而SQL Server总是使用一个定义的参数值,当前一个已编译计划使用不同的参数时问题出现了。然而,对于一个局部变量,当使用变量的语句被编译时,这个值是未知的,直到Recompile提示被使用。

Optimize For   Optimize For提示告知优化器似乎一个特别的值被用作一个变量或参数。执行使用一个真实的值,记住,Optimize For提示并不强制SQL Server被重编译,它仅仅指示SQL Server假定一个变量或参数有一个特别的值,此时,SQL Server已经决定查询需要优化。

Keep Plan   Keep Plan提示放宽一个查询的重编译阈值,特别查询访问临时表时。我们在前面的章节中提到过,当访问一个临时表的查询而表的变化达到6个时,查询被重编译。如果使用KeepPlan,则临时表的重编译阈值等同于固定表。

Keepfixed Plan Keepfixed plan提示因为优化冲突而阻止所有的重编译。定义该提示,查询将仅仅在强制重编译或基础表的架构改变时重编译。

Parameterization  Parameterization提示重定义了一个数据库的Parameterization选项。如果数据库被设置为Parameterization Forced,使用Parameterization提示的独立查询能够避免它,并且适合严格的条件列表才会参数化。或者,如果数据库设置为Parameterization Simple,独立的查询能够被在一步一步的基础上被参数化。

Use Plan   use Plan提示,在第八章中讨论过,作为一种强制SQL Server使用一个可能定义其他提示的计划的方式。定义的计划必须是XML格式,并能被从一个通过使用SET SHOWPLAN_XML ON选项的合适计划的查询中获取。因为USE Plan提示在查询提示中包括一个复杂的XML文档,它们是使用计划向导的最佳实践。

计划指南的意图

 尽管在大多数情况下推荐你允许查询优化器来决定每个查询的最佳计划,但有时查询优化器并不能得出最稳定性计划,你可能需要一个方式使用Hint获取合理的性能。

计划指南,在SQL Server2005中新增的功能,提出一种解决方案,可以给你一个机制仅增加Hint到查询而不需改变查询本身。首要地,一个计划向导告诉优化器,如果它试图优化一个特殊格式的查询,它应该增加一个Hint到查询。SQL Server支持三种类型的计划指南:SQL,Object和templete。

计划指南在标准版。企业版、评估版、和开发版中可用。如果从一个支持的SQL Server版本中detach一个包含计划指南的数据库,然后再附加玛个不支持的版本,如workgroup版本或Express版本中。SQL Server不使用任何计划指南。包含计划指南信息的元数据仍然可用。

计划指南的类型

可以使用sp_Create_plan_guide存储过程创建三种类型的计划。关于sp_create_plan_guide的用法,参看MSDN:

http://msdn.microsoft.com/zh-cn/library/ms179880.aspx

通用的格式如下:(注意顺序不能变化)
sp_Create_plan_guide 'plan_guide_name','statement_text','type_Of_plan_guide','object_name_or_batch_text','parameter_list','hints'

对象计划指南

一个object类型的计划指南,标示你对在出现在SQL Server对象的上下文的T-SQL感兴趣,可能是创建计划指南的数据库中的存储过程、用户自定义函数、或触发器。举例,我们假定一个存储过程Sales.GetOrderByCountry,使用country作为一个参数。在检查错误和其他有效性后,它返回一个结果集。更进一步,假定我们的测试已经决定给定的参数值"US"以最佳计划。这里使用Optimize for提示,以下示例创建一个计划指南,它与在基于应用程序的存储过程的上下文中所执行的查询匹配,并将 OPTIMIZE FOR 提示应用于该查询。

下面是此存储过程:

IF OBJECT_ID(N'Sales.GetSalesOrderByCountry', N'P') IS NOT NULL
DROP PROCEDURE Sales.GetSalesOrderByCountry;
GO
CREATE PROCEDURE Sales.GetSalesOrderByCountry
(
@Country_region nvarchar(60))
AS
BEGIN
SELECT *
FROM Sales.SalesOrderHeader AS h
INNER JOIN Sales.Customer AS c ON h.CustomerID = c.CustomerID
INNER JOIN Sales.SalesTerritory AS t
ON c.TerritoryID = t.TerritoryID
WHERE t.CountryRegionCode = @Country_region;
END

下面是为此存储过程中的查询所创建的计划指南:

EXEC sp_create_plan_guide
@name = N'Guide1',
@stmt = N'SELECT *
FROM Sales.SalesOrderHeader AS h
INNER JOIN Sales.Customer AS c
ON h.CustomerID = c.CustomerID
INNER JOIN Sales.SalesTerritory AS t
ON c.TerritoryID = t.TerritoryID
WHERE t.CountryRegionCode = @Country_region
',
@type = N'OBJECT',
@module_or_batch = N'Sales.GetSalesOrderByCountry',
@params = NULL,
@hints = N'OPTION (OPTIMIZE FOR (@Country_region = N''US''))';

一旦该计划在AdventureWorks2008数据库中被创建,每次存储过程"Sales.GetSalesOrderByCountry"被编译时,计划里揭示的语句如果实际参数值为'US'时被优化,这个存储过程中的其他语句不受此计划影响,如果定义的查询发生在Sales.GetSalesOrderByCountry外,计划指南不会调用。

SQL计划指南 

一个SQL类型的计划指南显示你关注特别的SQL语句,如一个独立的语句或一个特别的批处理。被送到SQL Server的T-SQL语句被通过CLR对象或扩展存储过程,或EXEC调用的其他动态SQL语句结构,而作为批处理运行。为了在计划指南中使用它们,它们的类型被设置为SQL。

对于一个单独的SQL语句,@module_or_beach参数应该被设置为NULL,以便SQL Server假定批处理和语句有同样的值,

如果是一个大的批处理,完整的批处理文本需要在@module_or_beach参数中定义。如果一个批处理被定义为一个SQL指南、这个文本需要和应用程序中的完全一样。这在前面章节已以讨论。这个规则并不与adhoc查询计划重用一样严格,但它们很接近。

这里有一个例子,指示SQL Server在一个特殊的查询被作为一个单独的查询时使用仅仅一个CPU(没有并行):

EXEC sp_create_plan_guide
@name = N'plan_SalesOrderHeader_DOP1',
@stmt = N'SELECT TOP 10 *
FROM Sales.SalesOrderHeader
ORDER BY OrderDate DESC
',
@type = N'SQL',
@module_or_batch = NULL,
@params = NULL,
@hints = N'OPTION (MAXDOP 1)';

一旦该查询指南被创建,每次该定义的语句在批处理中被碰到时,它有一个计划仅仅使用一个CPU。如果发生在一个在的批处理时,计划指南不调用。

模板计划指南

一个Templete类型的计划指南,仅仅使用Parameterization Forced或Parameterization Simple提示去重定义数据库的Parameterization数据库设置。有一个存储过程sp_get_query_template用来生成模板。sp_get_query_template的用法,请看MSDN:http://msdn.microsoft.com/zh-cn/library/ms186908.aspx
来看一个使用模板指南和强制参数化的例子,首先清除你的过程缓存,然后执行这两个查询:

DBCC FREEPROCCACHE;
GO
SELECT * FROM AdventureWorks.Sales.SalesOrderHeader AS h
INNER JOIN AdventureWorks.Sales.SalesOrderDetail AS d
ON h.SalesOrderID = d.SalesOrderID
WHERE h.SalesOrderID = 45639;
GO
SELECT * FROM AdventureWorks.Sales.SalesOrderHeader AS h
INNER JOIN AdventureWorks.Sales.SalesOrderDetail AS d
ON h.SalesOrderID = d.SalesOrderID
WHERE h.SalesOrderID = 45640;

用前面介绍的一个视图sp_cacheobjects查看,也可以使用sys.syscacheobjects(http://msdn.microsoft.com/zh-cn/library/ms187815.aspx):

SELECT objtype, dbid, usecounts, sql
FROM sp_cacheobjects
WHERE cacheobjtype = 'Compiled Plan';

SELECT objtype, dbid, usecounts, sql
FROM sys.syscacheobjects
WHERE cacheobjtype = 'Compiled Plan';

此时因为查询被看作复杂化,SQL Server并没有自动参数化。查询结果为null

为了创建一个强制这种类型的语句参数化。我们首先需要调用存储过程sp_get_query_template(http://msdn.microsoft.com/zh-cn/library/ms186908.aspx),传递两上变量作为输出参数。一个参数包含查询的参数化版本,另一个包含参数列表和数据类型。我们试着强制参数化(注意与上面查询比较):

DECLARE @sample_statement nvarchar(max);
DECLARE @paramlist nvarchar(max);
EXEC sp_get_query_template
N
'SELECT * FROM AdventureWorks.Sales.SalesOrderHeader AS h
INNER JOIN AdventureWorks.Sales.SalesOrderDetail AS d
ON h.SalesOrderID = d.SalesOrderID
WHERE h.SalesOrderID = 45639;
',
@sample_statement OUTPUT,
@paramlist OUTPUT
SELECT @paramlist as parameters, @sample_statement as statement
EXEC sp_create_plan_guide @name = N'Template_Plan',
@stmt = @sample_statement,
@type = N'TEMPLATE',
@module_or_batch = NULL,
@params = @paramlist,
@hints = N'OPTION(PARAMETERIZATION FORCED)';

DBCC FREEPROCCACHE;
GO
SELECT * FROM AdventureWorks.Sales.SalesOrderHeader AS h
INNER JOIN AdventureWorks.Sales.SalesOrderDetail AS d
ON h.SalesOrderID = d.SalesOrderID
WHERE h.SalesOrderID = 45639;
GO
SELECT * FROM AdventureWorks.Sales.SalesOrderHeader AS h
INNER JOIN AdventureWorks.Sales.SalesOrderDetail AS d
ON h.SalesOrderID = d.SalesOrderID
WHERE h.SalesOrderID = 45640;
GO

邀月工作室

 下文将继续关注计划指南的第二部分:计划指南的管理、计划指南的考虑因素、计划指南的有效性、从计划缓存中冻结计划。

相关文章:

小心!你的脸正在成为色情片主角……

编译丨福尔摩望本文经授权转载自 猎云网(ID:ilieyun)【导语】那的确是她的脸,但是在她不知情的情况下被无缝地移植到了别人的身体上。网络上曾出现过这样的视频:一名女子穿着粉色肩膊上衣,坐在床上&#xf…

【modbus】libmodbus库的移植与使用

一、源码下载 1、libmodbus官网 http://libmodbus.org/download/ 2、选择长期稳定版本libmodbus-3.0.6.tar.gz 下载链接:http://libmodbus.org/releases/libmodbus-3.0.6.tar.gz 3、MD5值 c80f88b6ca19cabc4ceffc195ca07771 libmodbus-3.0.6.tar.gz …

IntelliJ IDEA控制台输出中文乱码问题解决

如果还不行,那么再极端的设置,在IDEA启动的时候强制设置为UTF-8: 打开增加-Dfile.encodingUTF-8,重启Intellij IDEA 再或者直接在项目运行的时候加入UTF-8的设置 如果还是不行,那么你可能装了一个假的IDEA。

【数据库】mysql移植

一、源码下载 1、下载mysql源码 源码下载地址:选择版本:5.1.72(这是个老版本,高版本需要使用cmake) https://cdn.mysql.com/archives/mysql-5.1/mysql-5.1.72.tar.gz 历史版本下载地址 源码官网地址,在Oper…

HTML添加上传图片并进行预览

使用说明&#xff1a;新建文件&#xff0c;直接复制粘贴&#xff0c;保存文件为html 格式&#xff0c;在浏览器运行即可&#xff1b; 第一种&#xff1a; <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loos…

滴滴裁员2000多人,去年亏损超百亿

作者 | 非主流出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;据多家媒体的消息&#xff0c;在今天&#xff08;1 月 15 日&#xff09;上午的月度全员会上&#xff0c;滴滴 CEO 程维宣布公司将做好过冬准备&#xff0c;2019年会聚焦当前最重要的出行主业&#xff0c…

自己写的Treeview控件绑定数据源

首先在数据库中建表&#xff0c;表的格式如下id name parent_id代码如下&#xff1a;/// <summary>/// 添加根节点/// </summary>/// <param name"list">表的所有数据orm的List集合&#xff0c;object为表对应的实体对象</param>private…

【GDB】gdbserver的使用,远程调试开发板

0、将gdbserver拷贝到目标板子上 注:gdbserver在交叉编译工具目录/debug-root/usr/bin下 可用file命令查看 ------------------------------------------------------------ $ file gdbserver gdbserver: ELF 32-bit LSB executable, ARM, version 1 (SYSV), statically linke…

关于javascript代码优化的8点建议

前面的话 本文将详细介绍JS编程风格的几个要点 松耦合 当修改一个组件而不需要更改其他组件时&#xff0c;就做到了松耦合 1、将JS从CSS中抽离&#xff1a;不要使用CSS表达式 //不好的做法 .box{width: expression(document.body.offsetWidth ’px)} 2、将CSS从JS中抽离&#…

英伟达Q4净利同比降49%,还能继续躺赚吗?

图片来自英伟达官网整理 | 非主流出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;北京时间 2 月 15 日凌晨消息&#xff0c;英伟达公布了 2019 财年第四季度及全年财报。报告显示&#xff0c;英伟达第四季度营收为 22.05 亿美元&#xff0c;与上年同期的 29.11 亿美元…

管理磁盘和文件系统

管理磁盘和文件系统 实验案例一&#xff1a;迁移/home分区并设置磁盘配额 实验环境 公司原来安装的rhel5服务器采用了自动分区的方案&#xff0c;随着使用服务器的系统用户数量不断增多&#xff0c;根分区经常面临磁盘空间耗尽的情况&#xff0c;偶尔有几次还导致系统无法启动。…

TIOBE 2月编程语言排行榜:Python逼近C,Groovy重回TOP 20

作者 | 唐小引出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;新月伊始&#xff0c;一月一更的 TIOBE 编程语言社区发布了最新的 2 月编程语言排行榜。继 Python 语言成为 "2018年度编程语言" 的称号&#xff0c;在2月的编程语言排行榜中&#xff0c;Pyt…

【视频】YUV基础

参考网站:https://msdn.microsoft.com/en-us/library/windows/desktop/dd206750(v=vs.85).aspx YUV定义: YUV颜色空间主要用于优化彩色视频信号的传输,并使其向后兼容老式黑白电视。 其中“Y”表示明亮度(Luminance或Luma),也就是灰阶值; 而“U”和“V” 表示的则是色…

删除电脑里的空文件夹

发现电脑好多空文件夹&#xff0c;网上没有找到删除空文件夹的程序&#xff0c;自己动手谢了段代码 import java.io.File;/*** author zhangyanan*/ public class FileUtil { public static void main(String args[]) {String[] disk{"C:/","D:/","E:…

QT创建子对话框

1)根据UI文件动态加载对话框QUiLoader uiLoader;QFile file("://new/prefix1/testDailog.ui");QWidget *myWidget uiLoader.load(&file);myWidget->show();2) 创建非模态对话框 (需建立对话框类testDialog)testDialog *dialog new testDialog(this);dialog-…

对标Bert?刷屏的GPT 2.0意味着什么

作者 | 张俊林&#xff0c;中国中文信息学会理事&#xff0c;中科院软件所博士。目前在新浪微博 AI Lab 担任资深算法专家。在此之前&#xff0c;张俊林曾经在阿里巴巴任资深技术专家并负责新技术团队&#xff0c;以及在百度和用友担任技术经理及技术总监等职务。同时他是技术书…

Wedge 100-32X 100GbE Data Center Switch

1、总体设计 &#xff08;https://www.edge-core.com/productsList.php?cls1&cls25&cls367&#xff09; 基于 Facebook’s Wedge 100 design. 30个QSFP28光模块 使用broadcom Tomahawk 3.2 Tbps 芯片 COM-E CPU module&#xff0c;Intel Atom E3800 x86 processor 支…

【视频】对RTSP抓包,分析通讯流程

1、C–>S(客户端向服务端):OPTIONS命令查询服务器提供的方法 Request: OPTIONS rtsp://192.168.1.10:554/12 RTSP/1.0\r\n CSeq: 2\r\n User-Agent: LibVLC/2.2.8 (LIVE555 Streaming Media v2016.02.22)\r\n \r\n 2、S–>C:回应OPTIONS Response: RTSP/1.0 200 OK\…

JDBC知识全攻略

1. JDBC 的用途是什么&#xff1f;简单地说&#xff0c;JDBC 可做三件事&#xff1a;与数据库建立连接&#xff0c;发送SQL 语句&#xff0c;处理结果。下列代码段给出了以上三步的基本示例&#xff1a;Connection con DriverManager.getConnection ("jdbc:odbc:wombat&…

一次性掌握机器学习基础知识脉络 | 公开课笔记

来源 | AI科技大本营在线公开课 嘉宾 | 张相於 整理 | suiling 本次公开课AI科技大本营邀请到了阿里巴巴的高级算法专家张相於&#xff0c;他将从数据的概率分布开始介绍机器学习核心概念之间的有机关系&#xff0c;帮助大家建立知识脉络&#xff0c;做到知识的有机吸收。同时&…

Mongo、Redis、Memcached对比及知识总结

存储原理&#xff08;持久化&#xff09; Mongo Mongo的数据将会保存在底层文件系统&#xff0c;因此存储容量远大于redis和memcached。一个database中所有的collections以及索引信息会分散存储在多个数据文件中&#xff0c;即mongodb并没有像SQL数据库那样&#xff0c;每个表的…

【QT】Qtcreator的设计模式中将控件提升为自定义的控件

测试环境 在工程中添加自定义的控件 如&#xff1a;MyWidget 进入设计模式&#xff0c;右键需要提升的控件&#xff08;该控件的父类必须和自定义控件的父类相同&#xff0c;否则不能提升&#xff09;&#xff0c;选择“提升为…”&#xff0c;在新建提升的类中填写类的名称…

文件时间信息在测试中的应用

1 简介文件时间信息在测试中也有妙用&#xff5e; 通过记录模块运行前后的文件时间信息来识别运行前后发生变化的文件&#xff0c;从而识别模块运行前后的新增文件、删除的文件和内容发生变化的文件。 利用识别出来的发生变化的文件来减少复杂模块回归测试中采用新旧对比回归测…

SpringMVC之请求参数的获取方式

转载出处&#xff1a;https://www.toutiao.com/i6510822190219264516/ SpringMVC之请求参数的获取方式 常见的一个web服务&#xff0c;如何获取请求参数&#xff1f; 一般最常见的请求为GET和POST&#xff0c;get请求的参数在url上可以获取&#xff0c;post请求参数除了url上还…

生成假人脸、假新闻...AI虚拟世界正形成

整理 | 一一出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;AI 正在创造一个独特的虚拟&#xff08;虚假&#xff09;信息世界。一个人脸喂养生成网站火了。这个网站可以生成随机人脸图像&#xff0c;这些人脸没有姓名&#xff0c;在现实世界中并不存在&#xff0c;而…

【linux】ARM开发板上设置RTC时间,断电重启后,设置失效的原因分析

问题描述 linux中使用date设置时间后用hwclock -w同步到RTC&#xff0c;断电重启后&#xff0c;有时会失效 原因分析 保存时间戳 1、使用命令关机&#xff08;halt&#xff09;会调用rc0.d中的脚本&#xff1b; 2、使用命令重启&#xff08;reboot&#xff09;会调用rc6.d中…

【linux】NXP MFGTools工具配置文件详解

mfgtools\cfg.ini [profiles] chip Linux #对应mfgtools\Profiles\Linux\OS Firmware\中“Linux” #MfgTool2.exe中会使用路径&#xff1a;Profiles${chip}\OS Firmware [platform] board MY-IMX6 #没有用&#xff0c;可以忽略 [LIST] name Linux-3.14.52 #对应mfgtools\…

Python打造最强表白程序

作者 | 痴海转载自公众号痴海&#xff08;ID:ch726612&#xff09;情人节刚过&#xff0c;朋友圈又是刷屏的节奏。但热闹总是别人的&#xff0c;我们好像只有吃狗粮的份。时间总是飞快流逝&#xff0c;很多事情早已改变&#xff0c;但仿佛只有你的单身状态从未改变。单身久的我…

怎样加强你的意志力

每个人都有惰性&#xff0c;而且每天都在惰性进行斗争&#xff0c;而这个斗争在你死之前&#xff0c;是不会停止的。实际每个人都知道&#xff0c;每天应该坚持学习&#xff0c;早起早睡&#xff0c;可是到时候总是因为各种原因放弃。能坚持下来的人&#xff0c;离目标就更近一…