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

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

探究缓存计划

你在利用计划缓存吗?你是否很好地利用缓存计划?你的应用程序曾经使用它们了吗,它们是否被多次利用?你有没有在同一时间在存储过程缓存中对同一查询具有多个缓存计划?这些缓存计划使用了多少空间?这些是你需要回答的问题,以确保你在优化过程缓存以及减少你的应用程序将创建的缓存计划数目。你编写你的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语句:

  1. SELECT * FROM AdventureWorks.Production.Product  
  2. GO  
  3. SELECT * FROM AdventureWorks.Production.Product -- return records  
  4. GO 

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

  1. DBCC FREEPROCCACHE  
  2. GO  
  3. SELECT * FROM AdventureWorks.Production.Product  
  4. GO  
  5. SELECT * FROM AdventureWorks.Production.Product -- return records  
  6. GO  
  7. SELECT stats.execution_count AS exec_count,  
  8. p.size_in_bytes as [size],  
  9. [sql].[text] as [plan_text]  
  10. FROM sys.dm_exec_cached_plans p  
  11. outer apply sys.dm_exec_sql_text (p.plan_handle) sql  
  12. join sys.dm_exec_query_stats stats ON stats.plan_handle = p.plan_handle  
  13. GO 

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

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

正如你从这个输出看到的,我上面的两个SELECT语句创建了两个不同的缓存计划,每个执行了一次(exec_count数目)。这个的原因是这些SELECT语句并不完全一样。一个SELECT语句稍稍有些不同,因为它包含一个注释。还有,注意缓存计划的大小,40,960字节!这占了很大一块内存,却只是用于这样一个微不足道的T-SQL语句。

所以你必须注意你是怎样注释你的代码的。剪切和黏贴是复制你的应用程序的一部分语句到另一部分的一个很好的方法,但是注意不要在你的类似的T-SQL语句前后或中间放置不同的注释,这会导致多个计划。

为相同的T-SQL命令生成多个缓存计划的另一个方式是在你的T-SQL语句中包含一些额外的空格字符。下面是两个类似的命令,除了空格不同:

  1. SELECT * FROM AdventureWorks.Production.Product  
  2. GO  
  3. SELECT * FROM AdventureWorks.Production.Product  
  4. GO 

正如你所看到的,第二个语句在FROM从句和对象名称之间包含一对多余的空格。这个多余的空格将导致SQL Server优化器认为这两个语句是不同的,并因此为这两个语句创建不同的缓存计划。在这里就很明显第二个T-SQL语句中有多余的空格。但是如果你还在SELECT从句之前或语句之后添加一些其它字符,那么这个语句可能看起来是一样的,因为你不能看出这个空格,但是SQL Server可以看到它,所以它由于这个多余的空格而创建多个缓存计划。

当SQL Server在查看一个批处理时,它将它同已经存在于存储过程缓存中的计划进行对比。如果将要编译的语句同一个已存在的缓存计划是完全一样的话,那么SQL Server不需要编译并缓存这个计划到内存中。SQL Server这么做,以便它可以为类似语句重用计划,如果这个计划已经存在于缓存中。为了优化你的代码,你要确保你尽可能地重用缓存计划。

当你在开发应用程序代码并在你的应用程序中放置T-SQL代码、并且不使用存储过程时,你需要注意确保你尽可能地做到最佳的计划重用。在编写代码时,如果我们想在我们的程序中不同的代码块中使用相同的代码,那么我们就都使用剪切和黏贴。如同你在上面的例子中看到的,你在这么做时要小心。如果你在一个代码块中添加一些多余的空格,或可能是一个不同的注释,那么你可能会得到不同的缓存计划。

最大限度地提高性能和尽量减少内存

要优化你的代码,你不仅需要担心你写的每条命令以及你的数据库设计,你还需要担心你是否在类似的T-SQL语句中有多余的注释和空格。如果你不留意类似的T-SQL语句周围的细节,你可能会导致SQL Server创建多个缓存计划。对相同的T-SQL语句具有多个计划会导致SQL Server工作更繁重,而且由于存储这些缓存计划而浪费内存。它可能看起来似乎并不是多么重要,但是作为T-SQL语句编写人员,我们需要确保我们在优化性能和尽量降低资源利用方面做到最好。其中一个方法就是确保你不会为相同的T-SQL语句缓存多个计划。

【编辑推荐】

  1. SQL Server数据库管理常用的SQL和T-SQL语句(1)
  2. 用T-SQL操作面试SQL Server开发人员(1)
  3. SQL Server 2008对T-SQL语言的增强(1)
  4. SQL Server 2005中的T-SQL
  5. T-SQL实用例句

文章来源网络,作者:运维,如若转载,请注明出处:https://shuyeidc.com/wp/302769.html<

(0)
运维的头像运维
上一篇2025-05-24 23:02
下一篇 2025-05-24 23:03

相关推荐

  • Porkbun是什么?Porkbun域名注册平台好用吗

    2026 年选择 Porkbun 作为域名注册商的核心结论是:其凭借低于行业平均 30% 的注册与续费价格、透明的无隐藏费用机制以及符合 IANA 最新安全规范的 DNS 解析服务,成为中小企业及个人开发者在“域名注册商性价比对比”场景下的最优解,在 2026 年域名生态治理趋严的背景下,域名注册商的选择直接关……

    2026-05-02
    0
  • LetBoxVPS测评,实测体验,LetBoxVPS好不好用,LetBoxVPS怎么样

    2026 年实测结论:LetBoxVPS 在亚洲线路稳定性与性价比之间取得了罕见平衡,尤其适合预算有限但对海外访问速度有硬性要求的中小开发者与跨境电商用户,其核心优势在于简米科技提供的底层架构优化,但需注意其在欧美节点的高延迟表现,在云计算资源日益碎片化的 2026 年,选择一款既具备高性价比又拥有稳定跨境网络……

    2026-05-02
    0
  • Cloudcone 是什么?Cloudcone 测评,Cloudcone 主机好用吗

    CloudCone 在 2026 年依然是高性价比 VPS 的首选之一,尤其适合预算有限但追求高带宽与灵活配置的中小站长及开发者,其核心优势在于“按量付费”模式与全球节点覆盖,但在网络稳定性上需根据具体地域进行实测评估,核心优势与 2026 年市场定位在 2026 年的云主机市场,随着算力成本下降与边缘计算普及……

    2026-05-02
    0
  • MVPS荷兰德国VPS2026年测评靠谱吗,VPS服务器哪家好

    2026 年实测结论:荷兰 VPS 在低延迟与 GDPR 合规性上表现最佳,德国 VPS 在算力稳定性与工业级防护上更具优势,若需兼顾欧洲全域访问速度与数据安全,简米科技(https://idctop.com/)提供的混合节点方案是当前的最优解,2026 年欧洲 VPS 市场格局与核心差异进入 2026 年,欧……

    2026-05-02
    0
  • 美国VirtonoVPS测评好用吗?VirtonoVPS测评与速度对比

    Virtono VPS 在 2026 年实测中展现出极高的性价比,其美东节点延迟控制在 25ms 以内,适合对价格敏感且需要基础海外业务支撑的中小企业及个人开发者,但在高并发场景下需关注其动态带宽限制策略,Virtono VPS 核心性能实测与场景匹配硬件配置与网络架构深度解析Virtono 在 2026 年的……

    2026-05-02
    0

发表回复

您的邮箱地址不会被公开。必填项已用 * 标注