本文为翻译文章,原文地址:https://www.simple-talk.com/blogs/2009/08/03/stolen-pages-ad-hoc-queries-and-the-sins-of-dynamic-sql-in-the-application/ 

  

  前言

  在硬件资源非常有限的SQLServer服务器上进行开发,有一大优势,就是错误是可视化的,即你很快就会因为你的错误而受到惩罚。譬如,应用中过多使用ad-hoc动态查询的产生的问题会很快暴露出来。开发者可能会向你抱怨,数据库运行的越来越慢。你也将会发现服务器CPU的使用率非常高,甚至接近100%,但是在性能较差的时段,却没有阻塞的发生。

  在极端的情况下,你甚至可能接受到如下的错误:

  Error: 701, Severity: 17, State: 1
  There is insufficient system memory to run this query.

  或者

  Msg 8645, Level 17, State 1, Procedure , Line 1
  A time out occurred while waiting for memory resources to execute the query. Re-run the query. 

  分析

  你会发现运行过多的ad-hoc查询所有造成的不良影响。CPU利用率高是因为查询优化器需要编译大量的ad-hoc查询。内存压力是因为一些内存用来缓存ad-hoc查询生成的执行计划。换句话说,开发者使用了Ad-hoc查询,而不是使用存储过程或者参数化的查询。这是非常愚蠢的。

  一个编译好的执行计划大约占用70KB的空间,而一个存储过程的执行计划,根据其复杂度,大约占用2到3倍的空间。区别是每个存储过程只有一个执行计划。使用Ad-hoc查询,你将冒着每个查询都有一个单独的执行计划的风险。

  执行计划缓存起来是为了被重用的,SQLServer需要占用内存来存储执行计划,这部分内存按照申请方式称为StolenPages。其他占用StolenPages的对象包括了Connections、Locks 和 Transaction Context等一些内存Consumer以及线程和第三方代码消耗的内存。这是一个简单的日常任务分配内存的方式,但是当数据库接受到非常多的Ad-hoc查询时,将会产生麻烦。除非SQLServer可以确定查询可以自动的参数化或者说新的查询和已缓存的查询一致,否则SQLServer就会重新生成一个执行计划。可能不长时间,你就会看到数据缓存产生瓶颈 

  那么如何确定系统是否存在这种问题

  1. 检查编译查询计划的数量。SQLServer性能监视器将会显示 SQL Compilations/sec 有比较高的数值。理论上,SQL Recompilations/sec 和 Batch Requests/sec 的比率应该会非常低

  2. DBCC MemoryStatus 也会显示出stolen pages的数量会上升

  确定问题后,如何解决

  1. 使用存储过程来执行

  2. 使用参数化查询

  实例演示 略 具体见原网址

   如有不对的地方,欢迎拍砖,谢谢!O(∩_∩)O

Ad-hoc 查询以及动态SQL的罪恶[译]的更多相关文章

  1. MyBatis学习总结(三)——多表关联查询与动态SQL

    在上一章中我们学习了<MyBatis学习总结(二)——MyBatis核心配置文件与输入输出映射>,这一章主要是介绍一对一关联查询.一对多关联查询与动态SQL等内容. 一.多表关联查询 表与 ...

  2. Mybatis之关联查询及动态SQL

    前言 实际开发项目中,很少是针对单表操作,基本都会联查多表进行操作,尤其是出一些报表的内容.此时,就可以使用Mybatis的关联查询还有动态SQL.前几篇文章已经介绍过了怎么调用及相关内容,因此这里只 ...

  3. MyBatis中的条件查询(动态sql)

    本文将介绍使用MyBatis框架,编写DAO层接口类和接口类对应的sql映射文件,使用动态sql查询满足条件的用户集合. 首先,需要创建一个实体类User,供封装数据使用: package com.x ...

  4. Mybatis分页查询与动态SQL

    一.Mybatis的分页查询 由于第一二节较为详细讲述了Mybatis的环境搭建,文件配置,SQL编写和Java代码实现,所以接下来的讲述都将只抽取关键代码和mapper文件中的关键sql,详细的流程 ...

  5. Jfinal适用于条件查询的动态SQL语句生成工具

    条件查询是可能有为空字段,拼接SQL语句时候要屏蔽掉这些字段. package cn.pangpython.utils; import java.util.Iterator; import java. ...

  6. Mybatis.net与MVC入门配置及联合查询动态SQL拼接和简单事务

    第一次学习Mybatis.net,在博客园也找到好多资料,但是在配置成功之后也遇到了一些问题,尤其是在动态SQl拼接时候,这里把遇到的问题还有自己写的一个Demo贴出来,希望能帮到新手,有不适合的地方 ...

  7. SQL Server-聚焦深入理解动态SQL查询(三十二)

    前言 之前有园友一直关注着我快点出SQL Server性能优化系列,博主我也对性能优化系列也有点小期待,本来打算利用周末写死锁以及避免死锁系列的接着进入SQL Server优化系列,但是在工作中长时间 ...

  8. .Net程序员学用Oracle系列(28):PLSQL 之SQL分类和动态SQL

    1.SQL 语句分类 1.1.分类方法及类型 1.2.数据定义语言 1.3.数据操纵语言 1.4.其它语句 2.动态 SQL 理论 2.1.动态 SQL 的用途 2.2.动态 SQL 的语法 2.3. ...

  9. Mybatis第三篇【动态SQL】

    动态SQL 何为动态SQL??回顾一下我们之前写的SSH项目中,有多条件查询的情况,如下图 我们当时刚开始做的时候,是需要在Controller中判断SQL是否已经有条件了,因为SQL语句需要拼接起来 ...

随机推荐

  1. 解析ASP.NET Mvc开发之EF延迟加载 分类: ASP.NET 2014-01-04 01:29 4017人阅读 评论(1) 收藏

    目录: 从明源动力到创新工场这一路走来 解析ASP.NET WebForm和Mvc开发的区别 解析ASP.NET 和Mvc开发之查询数据实例 ----------------------------- ...

  2. Gen中的switch分析及lookupswitch与tableswitch指令

    int chooseNear(int i) { switch (i) { case 0: return 0; case 1: return 1; case 2: return 2; default: ...

  3. ActiveMQ开发注意要点

    目录1.如何保证消息的成功处理2.避免消息队列的并发3.消息有效期的管理4.过期消息,处理失败的消息如何处理 1.保证消息的成功处理消息发送成功后,接收端接收到了消息.然后进行处理,但是可能由于某种原 ...

  4. JavaScript 作用域(Scope)详解

    先对需要用到的名词解释一下,再通过例子深入理解 一.什么是作用域(Scope) [[scope]]:每个javascript函数都是一个对象,对象中有些属性我们可以访问,但有些不可以,这些属性仅供ja ...

  5. Node.js链式回调

    由于异步的关系,代码的书写顺序可能和执行顺序并不一样,可能想先执行A再执行B,但由于异步可能B要先于A执行.例如在OC中使用AFnetworking请求数据然后刷新页面,由于网络请求是用block实现 ...

  6. Extjs相关知识点梳理

      store是一个为Ext器件提供record对象的存储容器,行为和属性都很象数据表 方法:不列举继承来的方法 Store( Object config ) 构造,config定义为{ autoLo ...

  7. Mysql汉字乱码的解决

    在安装Mysql时其实可能选择使用GBK来处理汉字,由于以前没使用,所以就按默认的英语处理.不过,也可以C:\Program Files\MySQL\MySQL Server 6.8安装路径下的my文 ...

  8. C# 中 NPOI 库读写 Excel 文件的方法【摘】

    原作:淡水网志 NPOI 是开源的 POI 项目的.NET版,可以用来读写Excel,Word,PPT文件.在处理Excel文件上,NPOI 可以同时兼容 xls 和 xlsx.官网提供了一份 Exa ...

  9. javascript中的undefined与null的区别

    一.相似性 在JavaScript中,将一个变量赋值为undefined或null,老实说,几乎没区别. var a = undefined; var a = null; 上面代码中,a变量分别被赋值 ...

  10. linq中order by 和group by (含lambda表达式实现)以及综合案例

    一.Linq应用场景 linq的语法通过System.Linq下面的Enumerable类提供支持,也就是说,只要是实现了IEnumerable<T>的对象都可以使用Linq的语法来查询. ...