利用T-SQL代码提高缓存效率 减少内存消耗

发表于:2010-11-12 10:32

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:vivan    来源:51Testing软件测试网采编

  在这篇文章里,我将介绍怎样编写你的代码来提高缓存计划的重用。了解当有缓存计划或重用一个已有的计划时空格和注释会产生怎样的影响,这会帮助你降低你的应用程序缓存的计划数目。

  探究缓存计划

  你在利用计划缓存吗?你是否很好地利用缓存计划?你的应用程序曾经使用它们了吗,它们是否被多次利用?你有没有在同一时间在存储过程缓存中对同一查询具有多个缓存计划?这些缓存计划使用了多少空间?这些是你需要回答的问题,以确保你在优化过程缓存以及减少你的应用程序将创建的缓存计划数目。你编写你的T-SQL代码时有些细微的地方需要注意,它会使得SQL Server为相同的T-SQL代码去执行额外的工作来编译和缓存执行计划。

  在SQL Server可以处理一个T-SQL批处理之前,它需要创建一个执行计划。为了使SQL Server创建一个执行计划,它必须首先消耗一些宝贵的资源,比如CPU来编译一个T-SQL批处理。当一个计划编译后,它被缓存起来,因此在你的应用程序不止一次地调用相同的T-SQL语句时它可以被重用。如果你编写你的T-SQL代码来提高经常执行的T-SQL语句的缓存计划的重用,那么你就能够改进你的代码性能。

  随着SQL Server 2005的推出,微软提供了一些你可以用来探究缓存计划的DMV。通过使用这些DMV,你可以确认一些关于缓存计划的事情,下面是你可以确认的事情的简短列表:

  ● 与一个缓存计划相关的文本

  ● 一个缓存计划执行的次数

  ● 缓存计划的规模

  在后面我将告诉你怎样使用DM来探究缓存计划信息。

  由于注释或多余空格而使得有多个计划

  我相信你们所有人都有将代码放到存储过程中的想法。我们为了代码在一个应用程序中或多个应用程序间重用而这么做。但是,不是SQL Server执行的所有代码都包含在存储过程中。一些应用程序可能以顺序T-SQL代码来编写的。如果你在编写顺序T-SQL代码,那么你需要了解注释你的代码以及放置空格的方式可能会导致SQL Server为相同的T-SQL语句创建多个缓存计划。

  下面是一个T-SQL脚本的示例,它包含两个不同的T-SQL语句:

SELECT * FROM AdventureWorks.Production.Product 
GO 
SELECT * FROM AdventureWorks.Production.Product -- return records 
GO

  如同你所看到的,我有两个类似的T-SQL语句。两者都将返回AdventureWorks.Production.Product表的所有记录。那么你认为如果你运行这个代码SQL Server会创建多少缓存计划呢?为了回答这个问题,让我使用SQL Server 2005和SQL Server 2008中提供的一对DMV来看看这个缓存计划信息。为了查看这两个T-SQL语句产生的计划,我要运行下面的代码:

DBCC FREEPROCCACHE 
GO 
SELECT * FROM AdventureWorks.Production.Product 
GO 
SELECT * FROM AdventureWorks.Production.Product -- return records 
GO 
SELECT stats.execution_count AS exec_count, 
p.size_in_bytes as [size], 
[sql].[text] as [plan_text] 
FROM sys.dm_exec_cached_plans p 
outer apply sys.dm_exec_sql_text (p.plan_handle) sql 
join sys.dm_exec_query_stats stats ON stats.plan_handle = p.plan_handle 
GO

  在这个代码中,我首先通过运行DBCC FREEPROCCACHE命令来释放这个过程缓存。这个命令删除了内存中所有编译的执行计划。在这里关于这个命令我必须提一个忠告。你不要在一个生产环境中运行DBCC FREEPROCCACHE命令。在你的生产环境中这么做会删除你所有生成的缓存计划,而这么做可能会严影响你的生产环境,因为经常使用的计划会被重新编译。在释放了过程缓存之后,我执行我的两个不同的SELECT语句。最后,我将从一对不同的DMV获得的信息连接在一起为这两个SELECT语句返回一些缓存的计划信息。当我运行这个时,我从这个引用不同DMV的SELECT语句获得下面的输出:

exec_count size plan_text 
-------------------- ----------- --------------------------------------------------------------------
1 40960 SELECT * FROM AdventureWorks.Production.Product -- return records 
1 40960 SELECT * FROM AdventureWorks.Production.Product

21/212>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号