Вот версия, которая не использует устаревшие представления совместимости (sysprocesses не будут существовать вечно). Это немного более запутанно, чем ваш исходный запрос, но я проверил его, и планы из баз данных single_user или limited_user не возвращаются (они есть, если база данных возвращается в multi_user). Вы также можете добавить другие проверки, например, находится ли база данных в сети.
WITH valid_plans AS
(
SELECT plan_handle, usecounts, [dbid], [objectid], [sql_handle],
cpu, [io], [time]
FROM
(
SELECT cp.plan_handle, cp.usecounts, pa.attribute, pa.value,
[cpu] = qs.total_worker_time, [time] = qs.total_elapsed_time,
[io] = qs.total_logical_reads + qs.total_logical_writes,
qs.[sql_handle]
FROM sys.dm_exec_query_stats AS qs
INNER JOIN sys.dm_exec_cached_plans AS cp
ON qs.plan_handle = cp.plan_handle
CROSS APPLY sys.dm_exec_plan_attributes(cp.plan_handle) AS pa
) AS x
PIVOT (MAX(x.value) FOR x.attribute IN ([dbid], [objectid])) AS o
),
query_stats AS
(
SELECT
[dbid], [objectid] = CONVERT(INT, [objectid]),
[plan_handle], [sql_handle],
usecounts, cpu, [io],[time]
FROM valid_plans
WHERE [sql_handle] IS NOT NULL
AND [dbid] NOT IN
(
SELECT database_id
FROM sys.databases
WHERE user_access <> 0
)
)
SELECT database_name = DB_NAME(st.[dbid]),
[object_name] = OBJECT_NAME(st.objectid, st.[dbid]),
qs.usecounts,
avg_cpu_time = CAST(SUM(qs.[time])/(qs.usecounts*1.0) AS DECIMAL(12,2)),
avg_io = CAST(SUM(qs.[io])/(qs.usecounts*1.0) AS DECIMAL(12,2)),
avg_elapsed_time = SUM(qs.[time])/(qs.usecounts)/1000,
sql_text = st.[text],
qs.plan_handle
FROM query_stats AS qs
CROSS APPLY sys.dm_exec_sql_text(qs.[sql_handle]) AS st
GROUP BY
st.[dbid],
st.objectid,
qs.usecounts,
st.[text],
qs.plan_handle;