--临时工作负载优化
即席查询:也就是查询完没放到Cache当中,每次查询都要重新经过编译,并发高的时候很耗性能;
参数化查询: 一方面解决了重编译问题,但随着数据库数据数据的变更,统计信息的更新,可能缓存里的缓存计划已经不是查询优化器想要的结果;
Above SQL server 2008:
Optimize For Ad Hoc Workloads
第一次adhoc查询时候,cache会缓存一个存根的执行计划,本质上是一个300字节的标记,告诉SQLserver这个查询已经跑过了一次;如果使用默认值全部缓存计划最小大小为16KB;
那么问题来了,为什么微软工程师们不把默认值设为开启呢,微软的答复:当两个很复杂的编译的时候执行编译2次,这将是一件可怕的事情;
It Was a very edge case!
参数设置配置:
EXEC sp_configure 'show advanced options',1
RECONFIGURE
EXEC sp_configure 'optimize for ad hoc workloads',1
RECONFIGURE
界面:
查询执行一次AdHoc查询的大小及数量:
SELECT COUNT(1) AS COUNTS,
SUM(cast(size_in_bytes AS BIGINT)/1024/1024) AS CACHED_MB
FROM SYS.dm_exec_cached_plans
WHERE OBJTYPE='ADHOC' AND USECOUNTS=1
如果这个结果很大话,可以通过游标来批量执行:
----AUTHOR: KiNG
----DATE: 2016-08-18
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
DECLARE @PKID VARBINARY(64)
DECLARE CURSOR_FREE CURSOR FOR
SELECT PLAN_HANDLE
--,CP.usecountS ,
--ST.TEXT
FROM
SYS.dm_exec_cached_plans CP
CROSS APPLY SYS.DM_EXEC_SQL_TEXT(CP.plan_handle) ST
WHERE ST.TEXT LIKE 'SELECT%'
AND CP.objtype IN ('Prepared','Adhoc')
AND CP.cacheobjtype=N'Compiled Plan'
AND CP.usecounts=1
OPEN CURSOR_FREE
FETCH NEXT FROM CURSOR_FREE INTO @PKID
WHILE @@fetch_status=0
BEGIN
DBCC FREEPROCCACHE(@PKID)
FETCH NEXT FROM CURSOR_FREE INTO @PKID
END
CLOSE CURSOR_FREE;
DEALLOCATE CURSOR_FREE;