Som*_*Guy 50 performance sql-server memory cache query-performance
我一直在阅读 Kimberly Tripp 撰写的一些关于 SQL Server 计划缓存的精彩文章,例如:http : //www.sqlskills.com/blogs/kimberly/plan-cache-and-optimizing-for-adhoc-workloads/
为什么甚至有“针对临时工作负载进行优化”的选项?这不应该一直开着吗?无论开发人员是否使用 ad-hoc SQL,为什么不在每个支持它的实例上启用此选项(SQL 2008+),从而减少缓存膨胀?
Pet*_*eld 48
SQL Server 开发团队按照最少意外的原则工作 - 因此 SQL Server 通常禁用新功能,以保持与以前版本一样的行为。
是的,针对临时工作负载进行优化非常适合减少计划缓存膨胀 - 但请务必先进行测试!
Kalen Delaney 讲述了一个有趣的轶事,她问她的一位 Microsoft 工程师朋友是否在某些情况下不适合启用此功能。几天后他回来说 - 想象一个应用程序有很多不同的查询,每个查询总共运行两次。那么它可能是不合适的。可以说这样的应用程序并不多!
如果您的大多数查询执行不止一次(不完全是两次);这可能是不合适的。一般规则是,如果数据库中有许多一次性使用的即席查询,则将其打开;然而,像这样的应用程序仍然不多。
Kin*_*hah 23
以下是一些小代码,可帮助您确定“为临时工作负载切换优化开/关”是否有益。我们通常将其作为内部和客户端服务器运行状况检查的一部分进行检查。
这是最安全的启用选项,Brad here和 Glenn Berry here对此进行了很好的描述。
--- for 2008 and up .. Optimize ad-hoc for workload
IF EXISTS (
-- this is for 2008 and up
SELECT 1
FROM sys.configurations
WHERE NAME = 'optimize for ad hoc workloads'
)
BEGIN
DECLARE @AdHocSizeInMB DECIMAL(14, 2)
,@TotalSizeInMB DECIMAL(14, 2)
,@ObjType NVARCHAR(34)
SELECT @AdHocSizeInMB = SUM(CAST((
CASE
WHEN usecounts = 1
AND LOWER(objtype) = 'adhoc'
THEN size_in_bytes
ELSE 0
END
) AS DECIMAL(14, 2))) / 1048576
,@TotalSizeInMB = SUM(CAST(size_in_bytes AS DECIMAL(14, 2))) / 1048576
FROM sys.dm_exec_cached_plans
SELECT 'SQL Server Configuration' AS GROUP_TYPE
,' Total cache plan size (MB): ' + cast(@TotalSizeInMB AS VARCHAR(max)) + '. Current memory occupied by adhoc plans only used once (MB):' + cast(@AdHocSizeInMB AS VARCHAR(max)) + '. Percentage of total cache plan occupied by adhoc plans only used once :' + cast(CAST((@AdHocSizeInMB / @TotalSizeInMB) * 100 AS DECIMAL(14, 2)) AS VARCHAR(max)) + '%' + ' ' AS COMMENTS
,' ' + CASE
WHEN @AdHocSizeInMB > 200
OR ((@AdHocSizeInMB / @TotalSizeInMB) * 100) > 25 -- 200MB or > 25%
THEN 'Switch on Optimize for ad hoc workloads as it will make a significant difference. Ref: http://sqlserverperformance.idera.com/memory/optimize-ad-hoc-workloads-option-sql-server-2008/. http://www.sqlskills.com/blogs/kimberly/post/procedure-cache-and-optimizing-for-adhoc-workloads.aspx'
ELSE 'Setting Optimize for ad hoc workloads will make little difference !!'
END + ' ' AS RECOMMENDATIONS
END
Run Code Online (Sandbox Code Playgroud)
当您打开“ Optimize for Ad Hoc Workloads ”选项时,您将导致第二次运行的即席查询与第一次一样慢,因为您将编译执行计划并提取相同的数据(没有缓存)前两次。
这可能没什么大不了的,但您会在测试查询时注意到这一点。
那么现在会发生什么,没有打开这个选项和一个充满 1-Off Ad-Hoc 查询的缓存?
随着此优化功能的引入,缓存管理算法也进行了更新。
Kimberly Tripp 的文章还引用了Kalen Delaney关于此算法更改的帖子。
她解释得最好:
该更改实际上计算了计划缓存大小,当 SQL Server 识别出内存压力时,它将开始从缓存中删除计划。被移除的计划是没有被重复使用的廉价计划,这是一件好事。
这意味着当您需要释放资源时,那些讨厌的一次性计划将是第一个实施的计划。
“当 SQL Server 在必要时删除未使用的计划时,为什么我们需要‘优化 Ad Hoc 工作负载’? ”
我的回答是,如果您经常有大量动态 sql 生成大量非参数化广告-hoc 查询,那么打开这个功能就很有意义了。
您希望避免对系统资源造成压力,从而在您用完最大缓存内存空间后强制删除缓存计划/数据。
这是我写的一个查询,用于向您展示您当前缓存了多少 Ad-Hoc 计划以及它们占用了多少磁盘空间(结果会在一天内发生变化 - 因此请在重负载时进行测试):
--Great query for making the argument to use "Optimize for Ad Hoc Workloads":
SELECT S.CacheType, S.Avg_Use, S.Avg_Multi_Use,
S.Total_Plan_3orMore_Use, S.Total_Plan_2_Use, S.Total_Plan_1_Use, S.Total_Plan,
CAST( (S.Total_Plan_1_Use * 1.0 / S.Total_Plan) as Decimal(18,2) )[Pct_Plan_1_Use],
S.Total_MB_1_Use, S.Total_MB,
CAST( (S.Total_MB_1_Use * 1.0 / S.Total_MB ) as Decimal(18,2) )[Pct_MB_1_Use]
FROM
(
SELECT CP.objtype[CacheType],
COUNT(*)[Total_Plan],
SUM(CASE WHEN CP.usecounts > 2 THEN 1 ELSE 0 END)[Total_Plan_3orMore_Use],
SUM(CASE WHEN CP.usecounts = 2 THEN 1 ELSE 0 END)[Total_Plan_2_Use],
SUM(CASE WHEN CP.usecounts = 1 THEN 1 ELSE 0 END)[Total_Plan_1_Use],
CAST((SUM(CP.size_in_bytes * 1.0) / 1024 / 1024) as Decimal(12,2) )[Total_MB],
CAST((SUM(CASE WHEN CP.usecounts = 1 THEN (CP.size_in_bytes * 1.0) ELSE 0 END)
/ 1024 / 1024) as Decimal(18,2) )[Total_MB_1_Use],
CAST(AVG(CP.usecounts * 1.0) as Decimal(12,2))[Avg_Use],
CAST(AVG(CASE WHEN CP.usecounts > 1 THEN (CP.usecounts * 1.0)
ELSE NULL END) as Decimal(12,2))[Avg_Multi_Use]
FROM sys.dm_exec_cached_plans as CP
GROUP BY CP.objtype
) AS S
ORDER BY S.CacheType
Run Code Online (Sandbox Code Playgroud)
我不会说,“当你有 X MB 的时候”或“如果你的 Ad Hoc 的 X% 是一次性的”来打开它。
它不会影响 Sprocs、触发器、视图或参数化/准备好的 SQL - 只是 Ad-Hoc 查询。
我个人的建议是只在您的 Prod 环境中打开,但考虑在您的 Dev 环境中关闭它。
我说这仅适用于 Dev,因为如果您正在优化需要一分钟或更长时间才能运行的查询,那么您不希望运行它 3 次,然后才能看到它缓存的速度 -每次一次编辑它以找到最佳优化设计。
如果您的工作不涉及整天这样做,那么请发疯并让您的 DBA 在任何地方启用它。
小智 8
想想一个生产服务器,它只提供 5 个不同的查询,但每秒有数千个查询。您是 Microsoft SQL Server 开发团队。您将摆弄计划缓存。当您知道您的一些最大和最关键的客户(例如,Microsoft 的内部 SAP 实施)在同一个园区工作并使用您所在的同一自助餐厅时,您是否默认启用此行为?
| 归档时间: |
|
| 查看次数: |
33762 次 |
| 最近记录: |