Запрос DMV с использованием sys.dm_exec_sql_text завершается ошибкой, если какие-либо базы данных в однопользовательском режиме - PullRequest
0 голосов
/ 10 июня 2011

Использование следующего запроса для просмотра @ планов запроса

Тем не менее, я обнаружил, что у меня есть какая-либо однопользовательская база данных на экземпляре. Я сталкиваюсь со следующей ошибкой, если в ней уже есть пользователь Сообщение 924, уровень 14, состояние 1, строка 1 База данных '' уже открыта и может одновременно иметь только одного пользователя.

SELECT DB_NAME(st.dbid) AS database_name
,OBJECT_NAME(st.objectid, st.dbid) AS object_name
,cp.usecounts -- Use in place of qs.execution_count for whole plan count
,CAST(SUM(qs.total_worker_time)/(cp.usecounts*1.) as decimal(12,2)) AS avg_cpu_time
,CAST(SUM(qs.total_logical_reads + qs.total_logical_writes)/(cp.usecounts*1.) as decimal(12,2)) AS avg_io
,SUM(qs.total_elapsed_time)/(cp.usecounts)/1000 as avg_elapsed_time_ms
,st.text AS sql_text
,qs.plan_handle
FROM sys.dm_exec_query_stats qs
INNER JOIN sys.dm_exec_cached_plans cp ON qs.plan_handle = cp.plan_handle
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) st
WHERE NOT(DB_NAME(st.dbid) = 'SingleUserDBName')  -- Tried to filter it out but no joy
AND (DB_NAME(st.dbid) = 'MultiUserDBName')
GROUP BY st.dbid, st.objectid, cp.usecounts, st.text, qs.plan_handle

SQL Build 10.50.1746

1 Ответ

1 голос
/ 10 июня 2011

Вот версия, которая не использует устаревшие представления совместимости (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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...