Ang*_*ker 24 performance sql-server-2005 sql-server perfmon
我正在分析 SQL Server 2005 的一个实例,通过 PerfMon 的SQLServer:SQL Statistics - SQL Compilations/sec指标,我看到平均值约为 170 左右。
我拿出 SQL Profiler 并寻找 SP:Compile 或 SQL:Compile 事件。显然它们不存在。我确实发现Stored Procedure/SP:Recompile和TSQL/SQL:StmtRecompile事件。我在 Profiler 中看到的数据量表明这些是错误的事件,尽管我不确定。
所以我的问题。对其中任何一个的回答都会很棒。
Stored Procedure/SP:Recompile和TSQL/SQL:StmtRecompile事件在SQL事件探查器,他们不包括持续时间度量。如果这些事件无法查看对系统的时序影响,我该如何衡量这些事件对系统的影响。Tho*_*ger 37
SQL Compilations/sec是一个很好的指标,但仅当与Batch Requests/sec结合使用时。就其本身而言,每秒编译数并不能真正告诉您太多信息。
您看到的是 170。如果每秒批处理请求仅为 200(效果有点夸张),那么是的,您需要深入了解原因(很可能是过度使用临时查询和一次性计划)。但是,如果您的批处理请求每秒大约为 5000,那么每秒 170 次编译也不错。一般的经验法则是Compilations/sec应为 10% 或小于总Batch Requests/sec。
如果您真的想深入了解缓存的内容,请运行以下使用适当 DMV 的查询:
select
db_name(st.dbid) as database_name,
cp.bucketid,
cp.usecounts,
cp.size_in_bytes,
cp.objtype,
st.text
from sys.dm_exec_cached_plans cp
cross apply sys.dm_exec_sql_text(cp.plan_handle) st
Run Code Online (Sandbox Code Playgroud)
要获得所有一次性计划(计数):
;with PlanCacheCte as
(
select
db_name(st.dbid) as database_name,
cp.bucketid,
cp.usecounts,
cp.size_in_bytes,
cp.objtype,
st.text
from sys.dm_exec_cached_plans cp
cross apply sys.dm_exec_sql_text(cp.plan_handle) st
)
select count(*)
from PlanCacheCte
where usecounts = 1
Run Code Online (Sandbox Code Playgroud)
要获得与所有缓存计划相比,您拥有的一次性计数计划的比率:
declare @single_use_counts int, @multi_use_counts int
;with PlanCacheCte as
(
select
db_name(st.dbid) as database_name,
cp.bucketid,
cp.usecounts,
cp.size_in_bytes,
cp.objtype,
st.text
from sys.dm_exec_cached_plans cp
cross apply sys.dm_exec_sql_text(cp.plan_handle) st
where cp.cacheobjtype = 'Compiled Plan'
)
select @single_use_counts = count(*)
from PlanCacheCte
where usecounts = 1
;with PlanCacheCte as
(
select
db_name(st.dbid) as database_name,
cp.bucketid,
cp.usecounts,
cp.size_in_bytes,
cp.objtype,
st.text
from sys.dm_exec_cached_plans cp
cross apply sys.dm_exec_sql_text(cp.plan_handle) st
where cp.cacheobjtype = 'Compiled Plan'
)
select @multi_use_counts = count(*)
from PlanCacheCte
where usecounts > 1
select
@single_use_counts as single_use_counts,
@multi_use_counts as multi_use_counts,
@single_use_counts * 1.0 / (@single_use_counts + @multi_use_counts) * 100
as percent_single_use_counts
Run Code Online (Sandbox Code Playgroud)
至于通过 SQL Server 跟踪捕获的持续时间,它不适用于重新编译事件。看到计划编制所造成的持续时间或痛苦并不是那么重要,因为对于具体情况,您无能为力。解决方案是尝试通过计划重用(参数化查询、存储过程等)来限制编译和重新编译。
Jon*_*gel 11
应使用 PerfMon(或其他第 3 方解决方案)记录三个相关计数器。关键是要以某种方式记录这些统计数据。
正如Thomas Stringer 提到的,关注编译/批处理请求的比率是很好的。显然,越低越好,但只有“好”的指导方针,只有您可以决定什么是可以接受的。您将通过减少编译数量看到的绝对性能增益量取决于许多因素。
我还喜欢查看重新编译/编译的比率,以了解查询计划重用的数量。再次,越低越好。但是,在这种情况下,您确实希望在统计数据更改时在系统中进行重新编译(如果 DB 是只读的并且您进行了重新编译……可能有问题)。和我之前说的一样,只有“好”的指导方针。
您真正想要做的是随时间推移这些数字的趋势,因此,如果您看到任一比率出现大幅飙升,则表示部署了未正确使用查询计划的内容(理想情况下,这会在测试期间被捕获)——使用 Shark 的分析查询以找出罪魁祸首。此外,这里有一个可以找到经常重新编译的查询:
SELECT TOP 50
qs.plan_generation_num,
qs.execution_count,
qs.statement_start_offset,
qs.statement_end_offset,
st.text
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) st
WHERE qs.plan_generation_num > 1
ORDER BY qs.plan_generation_num DESC
Run Code Online (Sandbox Code Playgroud)
如果您还记录 CPU 使用情况的统计数据,则可以将所有统计数据关联在一起,以确定它的伤害程度以及您的修复有多大帮助。在实践中,我发现即使是核心 sproc 上的一个糟糕的查询计划策略也会使服务器瘫痪;显然是YMMV。