热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

《MicrosoftSqlserver2008Internals》读书笔记第九章PlanCachingandRecompilation(2)

《MicrosoftSqlserver2008Internals》索引目录:《MicrosoftSqlserver2008Internals》读书笔记--目录索引
《Microsoft Sql server 2008 Internals》索引目录:

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

在这一节,我们将继续关注Adhoc和参数化

Adhoc混合负载的优化

如果你的查询大多数是临时(adhoc)的,从来不会被重用,似乎浪费内存去缓存这些计划了。SQL Server 2008增加了一个配置选项在这种情况下也能满足你的需求。一旦选项启用,仅仅在第一次任何一个adhoc查询被编译时缓存一个存根,在第二次编译后,存根用以取代全部计划。

控制为Ad Hoc混合负载设置的优化

启用选项方法有二:
1、
EXEC sp_configure 'optimize for ad hoc workloads', 1; RECONFIGURE;
2、 在SQL Server Management Studio界面,高级-属性-中启用。
邀月工作室

编译计划存根

当 optimize for ad hoc workloads启用时,SQL Server缓存的存根仅仅大约300字节,并不包含查询计划的任何部分。它基本上仅仅是一个容器,以保持跟踪某一特殊的查询的前次编译。
这个存根包含了全部的缓存键和一个指向实际查询文本的指针。这个存根被存在SQL Manager缓存中。该存根的usecounts值始终是1,因为从来不会重用。

当生成编译计划存根的一个查询或批处理被重新编译时,这个存根被全编译计划代替。初始,usecounts被设置为1,因为不确定前一个查询是否与执行计划完全精确相同。

我们看一个例子:
EXEC sp_configure 'optimize for ad hoc workloads', 1; RECONFIGURE; GO USE Northwind2; DBCC FREEPROCCACHE; GO SELECT * FROM Orders WHERE CustomerID = 'HANAR'; GO SELECT usecounts, cacheobjtype, objtype, [text] FROM sys.dm_exec_cached_plans P CROSS APPLY sys.dm_exec_sql_text (plan_handle) WHERE cacheobjtype LIKE 'Compiled Plan%' AND [text] NOT LIKE '%dm_exec_cached_plans%'; GO SELECT * FROM Orders WHERE CustomerID = 'HANAR'; GO SELECT usecounts, cacheobjtype, objtype, [text] FROM sys.dm_exec_cached_plans P CROSS APPLY sys.dm_exec_sql_text (plan_handle) WHERE cacheobjtype LIKE 'Compiled Plan%' AND [text] NOT LIKE '%dm_exec_cached_plans%'; GO
邀月工作室
邀月工作室
如果关闭选项,执行:
EXEC sp_configure 'optimize for ad hoc workloads', 1; RECONFIGURE; GO

简单参数化(Simple Parameterization)

对于确定的查询,SQL Server能够决定是否需要把一个或多个常量参数化,此时,遵循相同基本模板的序列查询能够使用相同的计划。例如对于下列查询使用相同的计划:
SELECTFirstName,LastName,TitleFROMEmployees
WHEREEmployeeID=6;
SELECTFirstName,LastName,TitleFROMEmployees
WHEREEmployeeID=2;
SQLServer 在内部参数化这两个参数如下:
SELECTFirstName,LastName,TitleFROMEmployees
WHEREEmployeeID=@1;

USE Northwind2 GO DBCC FREEPROCCACHE; GO SELECT FirstName, LastName, Title FROM Employees WHERE EmployeeID = 6; GO SELECT FirstName, LastName, Title FROM Employees WHERE EmployeeID = 2; GO SELECT usecounts, cacheobjtype, objtype, [text] FROM sys.dm_exec_cached_plans P CROSS APPLY sys.dm_exec_sql_text (plan_handle) WHERE cacheobjtype = 'Compiled Plan' AND [text] NOT LIKE '%dm_exec_cached_plans%'; GO

查询结果类似如下:
邀月工作室

你应该注意到两个独立的查询由于不同的常量作为临时查询得到了缓存。然而,这些仅仅被考虑为shell queries(盒子查询),它的缓存仅仅使得(在以后相同常量的精准查询而可能被重用时)查找查询的参数化版本容易一些。这个shell查询不包含全部查询计划,而仅仅在相关预备计划中有一个指向全部计划的指针。

注意:不要把shell查询和计划存根混淆。一个shell查询包含查询的完整文本,使用至少16K内存。Shell查询仅仅被SQL Server认为可参数化的计划创建。而计划存根(plan stub),仅仅在内存中使用200字节,为不可参数化的、临时查询所创建,并且仅仅当optimize for ad hoc workloads选项设置为时生效。

上图中,注意第三行,objtype为Prepared,注意useCounts为2或4,意味着,一个查询被重用了两次或四次。

默认情况下,SQL Server对于决定参数自动化是非常保守的。仅仅当查询模板被考虑为安全时才会自动参数化。如果即便实际参数值变化时,一个查询计划也不改变,那么,这个模板是安全的。这个安全原则确保参数化不会消弱查询的性能。上面查询中Employee表有一个惟一的索引,因此任何使用相等比较式的EmployeeID,不会有两行。在惟一索引中使用seek是非常有用的,无论实际值如何。

然而,考虑到查询可能是一个不等比较式,或一个不惟一的列的相等比较式时。这种情况下,一些实际查询值会返回多行,或没有行,或一行。因此,一个查询是否最好的计划,取决于查询使用的值,是否被认为是安全的,是否参数化。这是整个查询优化的核心。

除了需求一个查询模板仅仅一个可能的计划外,还有许多查询结构不允许简单参数化,如下:
1、JOIN

2、BLUK INSERT

3、IN 列表

4、UNION

5、INTO

6、FOR BROWSER

7、OPTION

8、DISTINCT

9、TOP

10、WAITFOR语句

11、GROUP BY,HAVING,COMPUTE

12、全文谓词

13、序列化(subqueies)

14、FROM子句(Select语句含有表变量方法或全文表或OPENROWSET或OPENXML或OPENQUERY或OPENDATASOURCE

15、来自于<>比较谓词

简单参数化在使用下列结构的修改语句时被禁用&#xff1a;
1、带from子句的Delete/update

2、带&#xff08;含变量的&#xff09;set子句的Update

强制参数化(Forced Parameterization)

如果你的应用程序使用相同的查询&#xff0c;使用相同的计划明显会改善性能&#xff0c;但却没有自动参数化。或SQL Server出于安全考虑或使用了禁止的结构而没有采用参数化。SQL Server 2008提供了一种替代方案&#xff1a;一个数据库选项(Parameterization forced)

ALTER DATABASE SET PARAMETERIZATION FORCED;
该选项启用时&#xff0c;SQL Server将常量视作参数&#xff0c;有一些例外&#xff1a;
1、INSERT...EXECUTE语句

2、存储过程、触发器、或用户自定义函数内的语句。SQL Server已经为这些程序重用查询计划。

3、在客户端已经参数化的预备语句

4、包含XQuery方法调用的语句&#xff08;Statements that contain XQuery method calls, where the method appears in a context where its arguments would typically be parameterized, such as a WHERE clause. If the method appears in a context where its arguments would not be parameterized, the rest of the statement is parameterized.&#xff09;

5、T-SQL游标中的语句(API游标内部的Select语句被参数化&#xff09;

6、已经被废弃的查询结构

7、任何运行在(ANSI_PADDING or ANSI_NULLS设置为Off的&#xff09;上下文的任何语句

8、包含超过2097个Literals(直接常量)的语句

9、引用变量&#xff0c;如Where T.col2>&#61;&#64;p

10、包含RECOMPILE查询暗示的语句

11、包含一个COMPUTE子句的语句

12、包含一个WHERE CURRENT OF的子句

你需要谨慎为数据库设置这个选项&#xff0c;因为在优化期间所有的常量都参数化&#xff0c;那么频繁重用已经重用的计划将会导致性能急剧下降。

下文将继续关注简单参数化和预查询(Prepared Quries)


邀月注&#xff1a;本文版权由邀月和CSDN共同所有&#xff0c;转载请注明出处。
助人等于自助! 3w&#64;live.cn





推荐阅读
  • 在使用mybatis进行mapper.xml测试的时候发生必须为元素类型“mapper”声明属性“namespace”的错误项目目录结构UserMapper和UserMappe ... [详细]
  • MVC模式下的电子取证技术初探
    本文探讨了在MVC(模型-视图-控制器)架构下进行电子取证的技术方法,通过实际案例分析,提供了详细的取证步骤和技术要点。 ... [详细]
  • binlog2sql,你该知道的数据恢复工具
    binlog2sql,你该知道的数据恢复工具 ... [详细]
  • Hibernate全自动全映射ORM框架,旨在消除sql,是一个持久层的ORM框架1)、基础概念DAO(DataAccessorOb ... [详细]
  • 在Linux系统中使用EncFS实现文件夹加密
    为了保护个人隐私或敏感数据不被未经授权的访问,可以通过加密技术来增强安全性。本文介绍如何在Linux系统上使用EncFS工具创建和管理加密文件夹,以确保即使在系统登录状态下,特定文件夹中的数据也保持加密状态。 ... [详细]
  • 本文详细介绍了PHP中的几种超全局变量,包括$GLOBAL、$_SERVER、$_POST、$_GET等,并探讨了AJAX的工作原理及其优缺点。通过具体示例,帮助读者更好地理解和应用这些技术。 ... [详细]
  • 本文详细介绍了在PHP中如何获取和处理HTTP头部信息,包括通过cURL获取请求头信息、使用header函数发送响应头以及获取客户端HTTP头部的方法。同时,还探讨了PHP中$_SERVER变量的使用,以获取客户端和服务器的相关信息。 ... [详细]
  • 本文概述了在GNU/Linux系统中,动态库在链接和运行阶段的搜索路径及其指定方法,包括通过编译时参数、环境变量及系统配置文件等方式来控制动态库的查找路径。 ... [详细]
  • 本文探讨了使用Python实现监控信息收集的方法,涵盖从基础的日志记录到复杂的系统运维解决方案,旨在帮助开发者和运维人员提升工作效率。 ... [详细]
  • 本文探讨了互联网服务提供商(ISP)如何可能篡改或插入用户请求的数据流,并提供了有效的技术手段来防止此类劫持行为,确保网络环境的安全与纯净。 ... [详细]
  • 本文详细介绍了如何使用C#实现不同类型的系统服务账户(如Windows服务、计划任务和IIS应用池)的密码重置方法。 ... [详细]
  • 1、编写一个Java程序在屏幕上输出“你好!”。programmenameHelloworld.javapublicclassHelloworld{publicst ... [详细]
  • Python3爬虫入门:pyspider的基本使用[python爬虫入门]
    Python学习网有大量免费的Python入门教程,欢迎大家来学习。本文主要通过爬取去哪儿网的旅游攻略来给大家介绍pyspid ... [详细]
  • 七大策略降低云上MySQL成本
    在全球经济放缓和通胀压力下,降低云环境中MySQL数据库的运行成本成为企业关注的重点。本文提供了一系列实用技巧,旨在帮助企业有效控制成本,同时保持高效运作。 ... [详细]
  • 为何Compose与Swarm之后仍有Kubernetes的诞生?
    探讨在已有Compose和Swarm的情况下,Kubernetes是如何以其独特的设计理念和技术优势脱颖而出,成为容器编排领域的领航者。 ... [详细]
author-avatar
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有