• [译]SQL Passion Week 10: 计划缓存


    Week 9: Plan Caching

     
    Adhoc SQL Statements
     
    每次我们向SQL Server提交一个特定的SQL语句时, 查询计划为每一个unique query编译. 什么叫做unique query? 非常简单. SQL Server为完整的SQL语句(包含Hard-coded的值)产生一个Hash值, 作为一个查找值在计划缓存中使用. 如果找到该hash值,再该计划被复用. 否则将会编译一个新的计划, 所以想象一下现在执行下面3个查询
     
    SELECT * FROM Sales.SalesOrderHeader
    WHERE CustomerID = 11000
    GO
    SELECT * FROM Sales.SalesOrderHeader
    WHERE CustomerID = 30052
    GO
    SELECT * FROM Sales.SalesOrderHeader
    WHERE CustomerID = 11223
    GO

    这三个查询将会编译成不同的查询计划, 因为包含了一个hard-coded的参数值. 因此, 这三个查询计划都被放进了缓存中, 我们称之为 缓存污染.

    因为Hard-coded的原因, 这些查询计划很难被重用, 浪费了宝贵的缓存空间.

    Plan Stability
     
    当我们为查询语句或存储过程指定一个参数值执行, 可以轻易的套用计划复用, 但同时也可能会引发一个性能问题: 当某个查询计划实行一个Bookmark Lookup查找时(非聚集索引没有覆盖到查询), 如同week8讲过的,  如果只是检索少量数据,Bookmark Lookup是说的通的. 加入超过了临界点, 会比全表/索引扫描更有效率.
     
    但是一旦重用查询计划, 这些就不在考量之内(是否达到临界点), SQL Server会盲目信任重用的计划, 不管性能将会慢到何种地步.
     
    看下面的实际查询计划
     
    在这里,SQL Server盲目的复用了查询计划, 如图所示, 预测返回的行数和实际返回行数有着很大的差异. 缓存里的计划, 是基于假设查询只返回少量的记录, 但实际上返回了1499行. 我们在缓存中找到的是基于返回少量记录而做优化的计划.
     
    引发这些的根源在于我们没有一个计划稳定性, 基于估计的返回记录数, 我们得到的是Bookmark Lookup或者Table/Cluster Scan. 这是最常见的性能问题.
     
    解决这个问题的方法就是,通过包含索引来避免Bookmark Lookup, 不管参数如何变化, 得到的是同样的查询计划, 同样的查询性能.
     
     
     
  • 相关阅读:
    PHP独立环境安装与文件配置
    变量常量区别及用法
    PHP初步了解
    js dom操作基本单词和格式
    PHP 类的继承 访问修饰符 重写
    PHP面向对象基本概念 类与对象 静态属性 构造/析构方法
    人员定位系统项目整理
    json
    租房子ajax
    省市区三级联动用ajax实现
  • 原文地址:https://www.cnblogs.com/alphaqcode/p/5311724.html
Copyright © 2020-2023  润新知