在这篇文章里,我将介绍怎样编写你的代码来提高缓存计划的重用。了解当有缓存计划或重用一个已有的计划时空格和注释会产生怎样的影响,这会帮助你降低你的应用程序缓存的计划数目。
探究缓存计划
你在利用计划缓存吗?你是否很好地利用缓存计划?你的应用程序曾经使用它们了吗,它们是否被多次利用?你有没有在同一时间在存储过程缓存中对同一查询具有多个缓存计划?这些缓存计划使用了多少空间?这些是你需要回答的问题,以确保你在优化过程缓存以及减少你的应用程序将创建的缓存计划数目。你编写你的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 |
exec_count size plan_text -------------------- ----------- -------------------------------------------------------------------- 1 40960 SELECT * FROM AdventureWorks.Production.Product -- return records 1 40960 SELECT * FROM AdventureWorks.Production.Product |