查询优化器内核剖析之查询的执行与计划的缓存 Hint 提示

本篇议题如下:
查询的执行与计划的缓存
Hint 提示

首先看到第一个议题

查询的执行与计划的缓存

一旦查询被优化之后,存储引擎就使用选中的执行计划将结果返回,而被使用的这个执行 计划就会被保存在内存中一个被称之为“计划缓存”的地方,从而使得这个执行计划可以被重用, 从而节省 CPU 等资源。

尽管我们可以把执行计划缓存起来,便于重用,但是在某些情况,对于某些查询而言,计 划重用并不是很好的选择。这是为什么?这主要取决于表中数据的分布情况和查询中所使用的参 数,其实这种情况也被称为“参数嗅探(Parameter Sniffing,翻译过来还是很别扭的)”。

这里,我们就简单的说一下(详细的后续文章会慢慢的介绍)。例如,假设有这样一个查 询语句,如下图所示:

执行如下:

这个时候,存储过程运行,产生了一个执行计划,并且被缓存起来了。之后,又要运行这个查询,但是传入的参数不同,如下:

这个时候,这个查询可以使用之前创建的执行计划,但是这个时候也很有可能之前的执行 计划对与参数 870 不是最优化的。因为之前在生成的执行计划的时候,查询优化器是通过传入的 897 创建的执行计划。

试想:如果在表中的数据,有很多的 ProductId 的值都为 897,即使我们在 ProductId 上面 建立了索引,但是还有可能查询优化器决定在执行计划会采用扫描整表来获取数据。而对于参数 值为 870 的时候,在表中的存在相同的 ProductId 为 870 的数据很少,这个时候,如果采用索引 查找,可能会更快,那么就说明之前的执行计划中的整表扫描不适合了!

当然,这里只是简要的说明了一下,大家可能不是非常的明白,没关系,只要知道有这么 个情况就行了,我们在后面会详细剖析。

有时候,即使执行计划已经在计划缓存中存在了,但是有可能随着一些元数据的改变(修 改表的结构,移除索引等操作)会导致执行计划失效,或者不是比较优化的,或者甚至从计划缓 存中移除。当 SQL Server 存在内存压力的时候,一些执行计划也会被移除,释放内存。

Hint 提示

   在大部分情况下,查询优化器都会选择比较高效的执行计划,

但是,在有些情况下,查询优化器选择的执行计划没有达到预期的效果,或者说,查询优 化器做出了错误的选择。造成这个问题的原因是我们没有为 SQL Server 提供准确的信息,例如数 据库的统计信息过期了。

同时,在有些情况下,我们根据我们的经验和分析判断,发现 SQL Server 选择的执行计划 不是我们想要的。

当遇到上面的情况的时候,我们就可以给查询优化器一些提示信息,去告诉它该如何产生 执行计划,也就是我们自动的去干预查询优化器的默认行为。

   为了让大家有一个感性的认识,我这里举一个例子,对于下面的查询:

 

我们通过查询它的执行计划,如下图所示:

 

我们发现,这个查询计划不够高效,于是我们改写查询语句,如下:

在语句中,我们强制的使得查询优化器选择我们要的连接方式,

 执行计划如下:

 

大家如果对这里的知识不明白,没有关系,这里的例子只是让大家感受一下。

注意:一般情况下,我们没有必要去干扰查询优化器的工作,因为它会已经足够的“智能” 去选择更好的执行计划,除非我们非常有信心,并且证明我们用一些 Hint 会提升性能,这个时候, 我们可以加入 Hint。事实是,我们加入的 Hint 都是会产生很多的问题。

本篇就暂时到这里!后一篇文章就稍微详细一点的来看看与执行计划相关的一些话题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/94793.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++八股记录

C内存管理 C中,内存分成5个区。 栈:函数内局部变量;自动管理,效率高,但空间较小; 堆:new分配的内存块;手动管理,效率低,但空间大; 自由存储区&…

Qt应用开发(基础篇)——颜色选择器 QColorDialog

一、前言 QColorDialog类继承于QDialog,是一个设计用来选择颜色的对话框部件。 对话框窗口 QDialog QColorDialog颜色选择器一般用来让用户选择颜色,比如画图工具中选择画笔的颜色、刷子的颜色等。你可以使用静态函数QColorDialog::getColor()直接显示对…

指针(一)------指针概念+指针类型+野指针+指针运算+二级指针

💓博主csdn个人主页:小小unicorn ⏩专栏分类:C语言 🚚代码仓库:小小unicorn的代码仓库🚚 🌹🌹🌹关注我带你学习编程知识 指针(一) 指针是什么指针…

【阅读笔记】Graph of Thoughts: Solving Elaborate Problems with Large Language Models

Graph of Thoughts: Solving Elaborate Problems with Large Language Models Website & code: https://github.com/spcl/graph-of-thoughts 作者介绍了Graph of Thought (GoT):一个具备提高LLM提示能力,超越了思维链或思维树 (ToT) 等范式提供的能…

ES6中的箭头函数(arrow function)与普通函数的不同之处

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 语法简洁⭐ 没有自己的this⭐ 写在最后 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅!这个专栏是为那些对Web开发感兴趣、…

Streamlit 讲解专栏(十一):数据可视化-图表绘制详解(中)

文章目录 1 前言2 绘制交互式散点图3 定制图表主题4 增强数据可视化的交互性与注释步骤1步骤二 5 结语 1 前言 在上一篇博文《 Streamlit 讲解专栏(十):数据可视化-图表绘制详解(上)》中,我们学习了一些关…

wxWidgets从空项目开始Hello World

前文回顾 接上篇,已经是在CodeBlocks20.03配置了wxWidgets3.0.5,并且能够通过项目创建导航创建一个新的工程,并且成功运行。 那么上一个是通过CodeBlocks的模板创建的,一进去就已经是2个头文件2个cpp文件,总是感觉缺…

线上问诊:数仓开发(二)

系列文章目录 线上问诊:业务数据采集 线上问诊:数仓数据同步 线上问诊:数仓开发(一) 线上问诊:数仓开发(二) 文章目录 系列文章目录前言一、DWS1.最近1日汇总表1.交易域医院患者性别年龄段粒度问诊最近1日汇总表2.交易域医院患者…

mojo初体验

目录标题 mojo初体验试用地址变量定义参数可变性和所有权Structures后续 mojo初体验 试用地址 https://www.modular.com/get-started 与python基础语法很相似。 变量定义 let定义不可变变量var定义可变变量 参数可变性和所有权 下面是一个基本的函数: fn add…

得物一面,场景题问得有点多!

题目来源:https://www.nowcoder.com/discuss/525371909735792640 前文 本期是【捞捞面经】系列文章的第 1 期,持续更新中…。 《捞捞面经》系列正式开始连载啦,据说看了这个系列的朋友都拿到了大厂offer~ 欢迎星标订阅,持续更新…

手写Openfeign实现原理——极简版

文章目录 前言Openfeign实现思路前期准备基本依赖项 开始实现自定义注解自定义代理类定义创建代理对象的工厂InstantiationAwareBeanPostProcessor实现bean的注入OpenInstantiationAwareBeanPostProcessor 自定义 feign接口启动类小结 踩坑记录ImportComponent和Configuration区…

vscode远程调试php

使用vscode远程调试php的方法 1.安装remote ssh插件 2.连接服务器 可以点击左下角的绿色按钮,或者ctrlshiftp打开命令框输入remote ssh应该也有。 3.在服务器端vscode安装php debug插件 4.安装xdebug xdebug是用来调试php的软件,原本和vscode没什么关…