日期:2014-05-17  浏览次数:20617 次

ad-hoc即席查询优化以及sql执行计划的生成过程
本帖最后由 x_wy46 于 2014-01-03 14:16:14 编辑
再来一贴,最近看了不少东西,在学习的同时,遇到的是更多的疑问
就是关于ad-hoc sql优化的问题
还是《深入解析sqlserver2008》上面提到的问题

ad hoc 查询,说白了就是非绑定变量方式的查询,
可以使查询分析器中直接select where id=123
也可以是应用程序中的拼凑方式生成的sql 比如 where id=this.txtId.text;(txtId为页面的一个文本框)

本文也参考了这篇问题(不知道直接贴链接是不是违反论坛的规定,就直接粘过来文字好了)
《Microsoft Sql server 2008 Internal》读书笔记--第九章Plan Caching and Recompilation(2)

《淺談執行計畫快取和重用》

直接百度就可以找到


--开启optimize for ad hoc workloads后,
EXEC sp_configure 'optimize for ad hoc workloads', 1;
RECONFIGURE;
GO

select * from tableTest where id=1


SELECT usecounts, cacheobjtype, objtype, [text]
FROM sys.dm_exec_cached_plans P
        CROSS APPLY sys.dm_exec_sql_text (plan_handle)
WHERE cacheobjtype LIKE 'Compiled Plan%'
        AND [text] NOT LIKE '%dm_exec_cached_plans%';

--计划缓存其实我更习惯在select * from sys.syscacheobjects where dbid=DB_ID()里面看
--不知道这两种方式有啥区别,内部还是一个表吧?


----------结果
usecounts cacheobjtype objtype text
1 Compiled Plan Stub Adhoc select * from tableTest where id=1

--关键就是这里的Compiled Plan Stub,
--没有开启optimize for ad hoc workloads,缓存类型是Compiled Plan
--上面参考的文章中说:第一次任何一个adhoc查询被编译时缓存一个存根,
--在第二次编译后,存根用以取代全部计划。

--也就是说,存储Compiled Plan Stub类型的缓存,占用的内存比较少,
--第二次执行后完全相同sql后,才存储完整的编译
--这是我的理解,

--我的问题就在于:Compiled Plan Stub是个什么东西?
--执行计划是怎么缓存的?缓存中查询到的信息是不是真正的执行计划?

--开启了optimize for ad hoc workloads后,
--比如执行select * from table where id =1这个ad hoc 的sql
--这个sql的执行时依赖于执行计划,
--但是计划缓存中的Compiled Plan Stub貌似是个“半成品”的执行计划,
--此类型的缓存占用内存少什么的(参考“淺談執行計畫快取和重用”)
--难道说执行select * from table where id =1没有生成执行计划,
--或者说缓存中的信息(就是上面两种查询缓存的方式查询出来的信息)压根就不是执行计划







--csdn这种无法即见及所得的编辑方式真是蛋疼啊


------解决方案--------------------
执行计划是怎么缓存的?缓存中查询到的信息是不是真正的执行计划?
这个根据国外网站上的一个文章,说是预估执行计划
------解决方案--------------------
Compiled Plan Stub 是不是给翻译成了 编译计划存根 了。

有点像一个方程式,基础的东西,但具体的执行计划,还得带入一些,独立与每一个查询的参数,就像x,y,z等,然后生成的是最终的,实际执行的计划。