SQL Server 使用 OPTION (RECOMPILE) 和查询存储的查询

设置
        我们正在使用 WideWorldImporters 数据库,您可以从 Github 下载【sql-server-samples/samples/databases/wide-world-importers at master · microsoft/sql-server-samples · GitHub】。我正在运行SQL Server 2017 的最新 CU【https://sqlserverbuilds.blogspot.com/】,但这适用于任何版本的查询存储(SQL Server 2016 及更高版本)和 Azure SQL 数据库。下面的代码将启用查询存储,将 QUERY_CAPTURE_MODE 设置为 ALL(要了解各种不同以及建议用于生产的内容,请查看我的查询存储设置帖子【https://blog.csdn.net/hefeng_aspnet/article/details/140130527】),然后清除查询存储中的所有内容。我通常不建议您清除查询存储,但我们正在恢复演示数据库,这是一个演示,所以我要确保我们从头开始。最后,我们将创建一个用于测试的存储过程,该存储过程使用 RECOMPILE 创建,然后完全释放过程缓存。请注意,我不建议向存储过程添加 RECOMPILE 选项 - 这意味着每次执行时都会重新编译整个存储过程。我也不建议在生产中释放过程缓存 - 这只是为了演示目的。
USE [master];
GO
ALTER DATABASE [WideWorldImporters] SET QUERY_STORE = ON;
GO
ALTER DATABASE [WideWorldImporters] SET QUERY_STORE (OPERATION_MODE = READ_WRITE, QUERY_CAPTURE_MODE = ALL);
GO
ALTER DATABASE [WideWorldImporters] SET QUERY_STORE CLEAR;
GO
 
DROP PROCEDURE IF EXISTS Sales.usp_GetOrderInfo 
GO
 
CREATE PROCEDURE Sales.usp_GetOrderInfo
(@OrderID INT)
WITH RECOMPILE
AS
BEGIN
SELECT
o.OrderID,
o.CustomerID,
o.OrderDate,
ol.Quantity,
ol.UnitPrice
FROM Sales.Orders o
JOIN Sales.OrderLines ol
ON o.OrderID = ol.OrderID
WHERE o.OrderID = @OrderID;
END
GO
 
DBCC FREEPROCCACHE;
GO

测试
        首先,执行一个临时查询(不属于存储过程的一部分,具有 OPTION (RECOMIPLE) 提示):

SELECT
i.InvoiceID,
i.CustomerID,
i.InvoiceDate,
il.Quantity,
il.UnitPrice
FROM Sales.Invoices i
JOIN Sales.InvoiceLines il
ON i.InvoiceID = il.InvoiceID
WHERE i.InvoiceID = 54983
OPTION (RECOMPILE);
GO 10

如果我们检查计划缓存,您会注意到没有证据表明该查询已执行:

SELECT
qs.execution_count,
st.text, 
qs.creation_time
FROM sys.dm_exec_query_stats AS [qs] 
CROSS APPLY sys.dm_exec_sql_text ([sql_handle]) [st]
CROSS APPLY sys.dm_exec_query_plan ([plan_handle]) [p]
WHERE [st].[text][/text] LIKE '%Sales.Invoices%';
GO

但如果我们查看查询存储,我们确实会看到以下查询:
SELECT
[qsq].[query_id], 
[qsp].[plan_id],
[qsq].[object_id],
[rs].[count_executions],
[rs].[last_execution_time],
[rs].[avg_duration],
[rs].[avg_logical_io_reads],
[qst].[query_sql_text],
TRY_CONVERT(XML, [qsp].[query_plan]) AS [QueryPlan_XML],
[qsp].[query_plan] 
FROM [sys].[query_store_query] [qsq] 
JOIN [sys].[query_store_query_text] [qst]
ON [qsq].[query_text_id] = [qst].[query_text_id]
JOIN [sys].[query_store_plan] [qsp] 
ON [qsq].[query_id] = [qsp].[query_id]
JOIN [sys].[query_store_runtime_stats] [rs] 
ON [qsp].[plan_id] = [rs].[plan_id]
WHERE [qst].[query_sql_text] LIKE '%Sales.Invoices%';
GO 

如果我们展开 query_sql_text 列(由于空间原因删除了中间的文本),你会看到文本包含OPTION (RECOMPILE)。这很酷。

现在让我们执行使用 RECOMPILE 创建的存储过程,然后检查计划缓存:

EXEC Sales.usp_GetOrderInfo 57302;
GO 10
 
SELECT
qs.execution_count,
st.text, 
qs.creation_time
FROM sys.dm_exec_query_stats AS [qs] 
CROSS APPLY sys.dm_exec_sql_text ([sql_handle]) [st]
CROSS APPLY sys.dm_exec_query_plan ([plan_handle]) [p]
WHERE [st].[text][/text] LIKE '%Sales.Orders%';
GO

当我们检查查询存储时,我们确实看到了查询: 

SELECT
[qsq].[query_id], 
[qsp].[plan_id],
[qsq].[object_id],
OBJECT_NAME([qsq].[object_id]) AS ObjectName,
[rs].[count_executions],
[rs].[last_execution_time],
[rs].[avg_duration],
[rs].[avg_logical_io_reads],
[qst].[query_sql_text],
TRY_CONVERT(XML, [qsp].[query_plan]) AS [QueryPlan_XML],
[qsp].[query_plan] /* nvarchar(max) */
FROM [sys].[query_store_query] [qsq] 
JOIN [sys].[query_store_query_text] [qst]
ON [qsq].[query_text_id] = [qst].[query_text_id]
JOIN [sys].[query_store_plan] [qsp] 
ON [qsq].[query_id] = [qsp].[query_id]
JOIN [sys].[query_store_runtime_stats] [rs] 
ON [qsp].[plan_id] = [rs].[plan_id]
WHERE OBJECT_NAME([qsq].[object_id]) = 'usp_GetOrderInfo';
GO

概括
        无论在何处使用 OPTION(RECOMPILE)——在临时查询的语句级别还是在存储过程内的语句——以及在创建或执行期间在过程级别使用 RECOMPILE 选项时——查询文本、计划和执行统计信息仍会在查询存储中捕获。

参考:Queries with OPTION (RECOMPILE) and Query Store - Erin Stellato 

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

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

相关文章

[Vulnhub] digitalworld.local-JOY snmp+ProFTPD权限提升

信息收集 IP AddressOpening Ports192.168.101.150TCP:21,22,25,80,110,139,143,445,465,587,993,995 $ nmap -p- 192.168.101.150 --21,22,25,min-rate 1000 -sC -sV PORT STATE SERVICE VERSION 21/tcp open ftp ProFTPD | ftp-anon: Anonymous FTP logi…

基于Java中的SSM框架实现求职招聘网站系统项目【项目源码】

基于Java中的SSM框架实现线求职招聘网站系统演示 研究方法 本文的研究方法主要有: (1)调查法 调查法就是在系统的构思阶段,设计者对系统的功能和系统的现状有些不了解,需要去实地的去和本系统相关的区域进行调查&am…

函数的形状怎么定义?

在TypeScript中,函数的形状可以通过多种方式定义,以下是几种主要的方法: 1、函数声明:使用function关键字声明函数,并直接在函数名后的括号内定义参数,通过冒号(:)指定参数的类型&a…

Mojo AI编程语言(六)异常处理:提升代码健壮性

目录 1. 概述 2. 异常处理的基本概念 2.1 什么是异常 2.2 异常处理的重要性 3. Mojo语言中的异常处理机制 3.1 异常的定义 3.2 抛出异常 3.3 捕获异常 4. 异常处理的详细实现 4.1 多重异常捕获 4.2 异常链 4.3 使用自定义异常 4.4 异常的嵌套捕获 4.5 使用 asser…

数据结构——单链表详解(超详细)(2)

前言: 上一篇文章小编简单的介绍了单链表的概念和一些函数的实现,不过为了保证文章的简洁,小编把它分成了两篇来写,这一篇小编紧接上一篇文章继续写单链表函数功能的实现: 目录: 1.单链表剩余函数的编写 1.…

Lua 运算符

Lua 运算符 Lua 是一种轻量级的编程语言,广泛用于游戏开发、脚本编写和其他应用程序。它具有一套丰富的运算符,用于执行各种数学和逻辑操作。本文将详细介绍 Lua 中的运算符,包括算术运算符、关系运算符、逻辑运算符和其他特殊运算符。 算术…

高级java每日一道面试题-2024年7月17日

面试官: java中都有哪些引用类型? 我回答: 强引用(Strong Reference) 描述:这是最常见和最直观的引用类型,我们通常在代码中创建的对象引用就是强引用。例如,Object obj new Object();。只要强引用存在,…

Idea如何快速高效的修改项目的包名

文章目录 前言一、全局替换的快捷键二、弹出如下的界面 前言 当我们有时候在做项目迁移的时候,需要快速的修改项目的包名!那么如何快速高效的修改项目的报名呢? 经过尝试了很多方法!最简单的方法就是利用全局替换来直接替换报名&…

微服务到底是个什么东东?

微服务架构是一种架构模式,它提倡将单一应用程序划分成一组小的服务,服务之间互相协调、互相配合,为用户提供最终价值。 每个服务运行在其独立的进程中,服务和服务间采用轻量级的通信机制互相沟通(通常是基于 HTTP 的…

通过反射机制给已知属性赋值

最近在看spring,在手写spring框架之前,需要巩固一下反射。 反射有这样一个简单的例子,记录一下。 假如你知道age这个属性名,但是不知道属性类型,也可以写: 可以获取到属性的类型

昇思25天学习打卡营第11天 | mindspore 实现 ResNet 50 迁移学习

1. 背景: 使用 mindspore 学习神经网络,打卡第 11 天;主要内容也依据 mindspore 的学习记录。 2. 迁移学习介绍: mindspore 实现 ResNet 50 迁移学习; 具体 ResNet 50 的模型原理以及实现,可以参考本博客…

谈谈我对李彦宏说的“不要卷模型,要卷应用”的理解

我理解李彦宏的发言是强调人工智能技术应该关注应用而不是仅仅关注模型的发展。他认为AI技术已经从辨别式(discriminative)转向了生成式(generative),意味着AI不再仅仅是识别和分类问题,而是能够创造新的内…

设计模式-领域逻辑模式-事务脚本(Transaction Script)

事务脚本的特点 多数应用可看成由多个事务组成事务脚本将多个业务逻辑组织成单个过程事务间相互修改各自产生的数据 事务脚本的运行机制 使用事务脚本时,领域逻辑主要通过系统所执行的事务来组织。例如:预定酒店过程。 事务脚本的组织 将整个事务脚本放…

【BUG】已解决:IndexError: list index out of range

已解决:IndexError: list index out of range 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页,我是博主英杰,211科班出身,就职于医疗科技公司,热衷分享知识,武汉城市开发者社区…

微信小程序:2.全局开发

app实例 简介 app.js中注册小程序实例的方法App拥有生命周期回调函数、错误监听函数、页面不存在监听函数等 生命周期回调函数 onLaunch(options) {//监听小程序初始化 console.log("监听小程序初始化",options); }, onShow (options) {//监听小程序启动或切前台…

Ubuntu串口调试单片机

来自🥬🐶程序员 Truraly | 田园 的博客,最新文章首发于:田园幻想乡 | 原文链接 | github (欢迎关注) 文章目录 brltty 导致 USB 转串口连接失败串口调试工具直接操作串口puttySerial Monitor | vscode 插件minicom(推荐)舍友在搞 c-sky 的单片机,囚来了一块玩玩,尝…

【C++】C++中的getcwd函数详解

目录 一.getcwd函数是什么 二.getcwd函数怎么用 一.getcwd函数是什么 在C中&#xff0c; getcwd 是一个用于获取当前工作目录的函数&#xff0c;它是POSIX标准的一部分&#xff0c;定义在 <unistd.h> 头文件中&#xff08;在Windows上&#xff0c;它定义在 <direct…

对服务器进行基本了解(二)

目录 一. 云服务器数据库 1.查看MYSQL版本 2.查看mysql的运行状态 3.运行mysql 4. 进入mysql的用户 5. 更改用户密码 6. 查找mysql端口号 7. 创建一个数据库 8. 查看用户 9. 查看数据库 10. 显示数据库的表 11. 修改用户的host 12. 对用户赋权 13. 开放指定端…

python程序设定定时任务

在 Windows 系统上,您可以使用任务计划程序(Task Scheduler)来设置定时任务,执行 Python 文件。以下是具体步骤: 步骤 1:准备 Python 文件 假设有一个名为 script.py 的 Python 脚本。确保它可以在命令行中正确运行。 步骤2:找到Python可执行文件的位置 知道Python可…

【学习笔记】无人机系统(UAS)的连接、识别和跟踪(一)-3GPP TS 23.256 技术规范概述

3GPP TS 23.256 技术规范&#xff0c;主要定义了3GPP系统对无人机&#xff08;UAV&#xff09;的连接性、身份识别、跟踪及A2X&#xff08;Aircraft-to-Everything&#xff09;服务的支持。 3GPP TS 23.256 技术规范&#xff1a; 以下是文档的核心内容总结&#xff1a; UAV系…