我一直在深入研究SQL Server查询存储,并且经常看到对“临时”查询的引用。但是,我还没有看到查询存储确定什么是即席查询。我已经看到了可以将其推断为没有参数的查询或仅执行一次查询的地方。为此是否存在正式定义?我的意思不是一般。我的意思是,它与查询存储有关。
例如,此页面显示了一个从查询存储中删除临时查询的示例,但是它所使用的条件似乎是执行计数仅为一个。这似乎是临时查询的奇怪定义。顺便说一句,如果您转到页面,请搜索“删除临时查询”。
我一直在深入研究SQL Server查询存储,并且经常看到对“临时”查询的引用。但是,我还没有看到查询存储确定什么是即席查询。我已经看到了可以将其推断为没有参数的查询或仅执行一次查询的地方。为此是否存在正式定义?我的意思不是一般。我的意思是,它与查询存储有关。
例如,此页面显示了一个从查询存储中删除临时查询的示例,但是它所使用的条件似乎是执行计数仅为一个。这似乎是临时查询的奇怪定义。顺便说一句,如果您转到页面,请搜索“删除临时查询”。
Answers:
经过一番搜索,我无法从Microsoft文档中找到具体且令人满意的来源来回答此问题。那里有许多关于adhoc / ad-hoc / ad hoc的好的第三方描述和定义,但是对于这个问题的特殊性,我认为最接近源头的是理想的。
跳过像SO这样的通用(但仍然准确)的定义(感谢SqlWorldWide),如果我们看一下文档中有关该主题的内容,它与您提到的关于定义基于执行次数的内容是一致的,我认为我们可以将其视为事实。
当此选项设置为1时,第一次编译批处理时,数据库引擎会在计划缓存中存储一个小的已编译计划存根,而不是完整的已编译计划。通过不允许计划缓存填充未使用的已编译计划,这有助于减轻内存压力。编译后的计划存根允许数据库引擎识别该临时批处理之前已经编译过,但是仅存储了编译后的计划存根,因此当再次调用(编译或执行)该批处理时,数据库引擎将编译该批处理...并将完整的已编译计划添加到计划缓存中。
这样看来,ad hoc查询服务器配置选项也将单个执行的定义用作ad hoc的定义。如果查询继续执行并生成相同的计划,它将不再被视为原来的计划。
关于“查询存储的最佳做法 ”的文章也与此一致,
将不同的query_hash值的数量与sys.query_store_query中的条目总数进行比较。如果比率接近1,则您的临时工作负载将生成不同的查询。
当然,这是针对尚未被用作存储过程,参数化等的查询,因为可以立即对其进行适当识别和处理。
因此,基于所有这些,我们可以说在以下情况下将查询视为即席查询:
对于临时查询,如sys.query_store_query文档中所述,DMV中的object_id列sys.query_store_query
将为0 :
object_id:
查询所属的数据库对象的ID(存储过程,触发器,CLR UDF / UDAgg等)。如果查询未作为数据库对象的一部分执行(即席查询),则为0。
您可以基于该值标识即席查询,即使未明确将其声明为“这是即席查询的定义”。:)
特设从sys.dm_exec_cached_plans DMV的objtype
在docs.microsoft.com列。
临时:临时查询。引用通过使用osql或sqlcmd而不是远程过程调用的语言事件提交的Transact-SQL。
此列的一种用法是查看具有多个计划的查询,以查看多个计划是否由引起Adhoc
。
SELECT DISTINCT
QCP.objtype
,MultipleQ.PlanCount
,qStat.query_hash
,sText.text AS QueryText
FROM (
SELECT query_hash,
COUNT(query_hash) AS PlanCount
FROM sys.dm_exec_query_stats
GROUP BY query_hash
) AS MultipleQ
INNER JOIN sys.dm_exec_query_stats qStat ON MultipleQ.query_hash = qStat.query_hash
INNER JOIN sys.dm_exec_cached_plans QCP
ON QCP.plan_handle = qStat.plan_handle
CROSS APPLY sys.dm_exec_sql_text(qStat.sql_handle) AS sText
CROSS APPLY sys.dm_exec_query_plan(qStat.plan_handle) AS qp
WHERE PlanCount > 1
ORDER BY MultipleQ.PlanCount DESC