本文为翻译文章,原文地址: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. Win7上装CentOS7 双系统

    今天折腾了半天,终于在Win7上把CentOS装上了,Win7和CentOS双系统共存,可自由切换. 你问我为什么不装在虚拟机上,我只能说我的电脑卡得一B. 装机参考: 1.Window7+CentO ...

  2. 【树】Binary Tree Right Side View

    题目: Given a binary tree, imagine yourself standing on the right side of it, return the values of the ...

  3. Windows里如何正确安装Redis以服务运行(博主推荐)(图文详解)

    不多说,直接上干货! 注意 : Redis官方并没有提供Redis的windows安装包,但在github上, 有相关的下载地址.       一.Redis的下载地址 相关的下载地址,如下:     ...

  4. nodejs + express 热更新

    以前node中的express框架,每次修改代码之后,都需要重新npm start 才能看到改动的效果,非常麻烦,所以这里引入nodemon模块,实现了不用重启也能自动更新这样的好处 1.全局安装no ...

  5. Linux-(tar,gzip,df,du)

    tar命令 首先要弄清两个概念:打包和压缩.打包是指将一大堆文件或目录变成一个总的文件:压缩则是将一个大的文件通过一些压缩算法变成一个小文件. 为什么要区分这两个概念呢?这源于Linux中很多压缩程序 ...

  6. 反应器(Reactor)模式

    Java NIO非堵塞技术实际是采取反应器模式,或者说是观察者(observer)模式为我们监察I/O端口,如果有内容进来,会自动通知我们,这样,我们就不必开启多个线程死等,从外界看,实现了流畅的I/ ...

  7. jQuery.on() 函数

    1.绑定所有的<p>元素// 为所有P元素分别绑定click事件处理函数handler$("p").on("click", handler); 2. ...

  8. grafana安装

    1 wget https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-5.2.4-1.x86_64.rpm2 sudo ...

  9. github删除仓库

    有的时候github的仓库创建错误了,不用了,想删除仓库 1.进入仓库,选择设置 2.拉到最下面,有一个Delete this repository删除仓库按钮,点击 3.输入需要删除的仓库的名称,直 ...

  10. Css3不透明

    Css3允许你使用opacity(不透明)属性设置元素的不透明度 实例: <img src="1.jpg" alt=“view”> img{ opacity:0.45: ...