Вопрос

Можно ли получить разбивку по загрузке процессора по базе данных?

Я в идеале ищу интерфейс типа диспетчера задач для SQL server, но вместо того, чтобы смотреть на загрузку процессора каждым PID (например taskmgr) или каждый SPID (например spwho2k5), я хочу просмотреть общую загрузку процессора каждой базы данных.Предположим, что имеется один экземпляр SQL.

Я понимаю, что можно было бы написать инструменты для сбора этих данных и составления отчетов по ним, но мне интересно, есть ли какой-нибудь инструмент, который позволяет мне в режиме реального времени видеть, какие базы данных вносят наибольший вклад в sqlservr.exe Загрузка процессора.

Это было полезно?

Решение

Вроде того.Ознакомьтесь с этим запросом:

SELECT total_worker_time/execution_count AS AvgCPU  
, total_worker_time AS TotalCPU
, total_elapsed_time/execution_count AS AvgDuration  
, total_elapsed_time AS TotalDuration  
, (total_logical_reads+total_physical_reads)/execution_count AS AvgReads 
, (total_logical_reads+total_physical_reads) AS TotalReads
, execution_count   
, SUBSTRING(st.TEXT, (qs.statement_start_offset/2)+1  
, ((CASE qs.statement_end_offset  WHEN -1 THEN datalength(st.TEXT)  
ELSE qs.statement_end_offset  
END - qs.statement_start_offset)/2) + 1) AS txt  
, query_plan
FROM sys.dm_exec_query_stats AS qs  
cross apply sys.dm_exec_sql_text(qs.sql_handle) AS st  
cross apply sys.dm_exec_query_plan (qs.plan_handle) AS qp 
ORDER BY 1 DESC

Это позволит вам получить запросы в кэше плана в порядке того, сколько процессора они израсходовали.Вы можете периодически запускать это, как в задании агента SQL, и вставлять результаты в таблицу, чтобы убедиться, что данные сохраняются после перезагрузок.

Когда вы прочтете результаты, вы, вероятно, поймете, почему мы не можем напрямую сопоставить эти данные с отдельной базой данных.Во-первых, один запрос также может скрыть свою истинную родительскую базу данных, выполняя подобные трюки:

USE msdb
DECLARE @StringToExecute VARCHAR(1000)
SET @StringToExecute = 'SELECT * FROM AdventureWorks.dbo.ErrorLog'
EXEC @StringToExecute

Запрос будет выполнен в базе данных MSDB, но он будет опрашивать результаты из AdventureWorks.Где мы должны распределить потребление процессора?

Становится еще хуже, когда ты:

  • Объединение между несколькими базами данных
  • Запустите транзакцию в нескольких базах данных, и операция блокировки охватит несколько баз данных
  • Запускайте задания агента SQL в MSDB, которые "работают" в MSDB, но создают резервные копии отдельных баз данных

Это продолжается все дальше и дальше.Вот почему имеет смысл настраивать производительность на уровне запросов, а не на уровне базы данных.

В SQL Server 2008R2 корпорация Майкрософт представила функции управления производительностью и приложениями, которые позволят нам упаковать единую базу данных в распространяемый и развертываемый пакет DAC, и они обещают упростить управление производительностью отдельных баз данных и их приложений.Однако это все равно не дает того, что вы ищете.

Для получения дополнительной информации ознакомьтесь с Репозиторий T-SQL в Toad World's SQL Server wiki (ранее в SQLServerPedia).

Обновлено 1/29, чтобы включить общие цифры, а не только средние.

Другие советы

SQL Server (начиная с 2000 года) установит счетчики производительности (доступные для просмотра с помощью Performance Monitor или Perfmon).

Одной из категорий счетчиков (при установке SQL Server 2005 является:) - SQLServer: базы данных

С одним экземпляром для каждой базы данных.Доступные счетчики, однако, не предоставляют счетчик загрузки процессора в процентах или что-то подобное, хотя есть несколько счетчиков скорости, которые вы могли бы использовать, чтобы получить хорошую оценку процессора.Примером может быть, если у вас есть 2 базы данных, и измеряемая скорость составляет 20 транзакций в секунду в базе данных A и 80 транзакций в секунду в базе данных B - тогда вы бы знали, что A обеспечивает примерно 20% от общего объема процессора, а B - остальные 80%.

Здесь есть некоторые недостатки, поскольку предполагается, что вся выполняемая работа привязана к процессору, чего, конечно, с базами данных нет.Но я верю, что это было бы началом.

Вот запрос, который покажет фактическую базу данных, вызывающую высокую нагрузку.Он полагается на кэш запросов, который может часто очищаться в сценариях с низким объемом памяти (что делает запрос менее полезным).

select dbs.name, cacheobjtype, total_cpu_time, total_execution_count from
    (select top 10
        sum(qs.total_worker_time) as total_cpu_time,  
        sum(qs.execution_count) as total_execution_count, 
        count(*) as  number_of_statements,  
        qs.plan_handle
    from  
        sys.dm_exec_query_stats qs 
    group by qs.plan_handle
    order by sum(qs.total_worker_time) desc
    ) a
inner join 
(SELECT plan_handle, pvt.dbid, cacheobjtype
FROM (
    SELECT plan_handle, epa.attribute, epa.value, cacheobjtype
    FROM sys.dm_exec_cached_plans 
        OUTER APPLY sys.dm_exec_plan_attributes(plan_handle) AS epa
     /* WHERE cacheobjtype = 'Compiled Plan' AND objtype = 'adhoc' */) AS ecpa 
PIVOT (MAX(ecpa.value) FOR ecpa.attribute IN ("dbid", "sql_handle")) AS pvt
) b on a.plan_handle = b.plan_handle
inner join sys.databases dbs on dbid = dbs.database_id

Я думаю, что ответ на ваш вопрос - нет.

Проблема в том, что одно действие на компьютере может вызвать нагрузку на несколько баз данных.Если у меня есть процесс, который считывает данные из базы данных конфигурации, регистрируется в базе данных ведения журнала и перемещает транзакции в различные базы данных и из них в зависимости от типа, как мне разделить загрузку процессора?

Вы могли бы разделить загрузку процессора на загрузку транзакций, но это опять же грубый показатель, который может ввести вас в заблуждение.Например, как бы вы разделили доставку журналов транзакций из одной базы данных в другую?Загружается ли процессор при чтении или записи?

Вам лучше обратить внимание на скорость транзакций для компьютера и нагрузку на процессор, которую это вызывает.Вы также могли бы профилировать хранимые процедуры и посмотреть, не отнимает ли какая-либо из них чрезмерно много времени;однако это не даст вам желаемого ответа.

Имея в виду все сказанное выше.
Начиная с SQL Server 2012 (может быть 2008 ?) , есть столбец идентификатор базы данных в системные.dm_exec_sessions.
Это дает нам простой расчет центрального процессора для каждой базы данных для в данный момент подключен сеансы.Если сеанс отключили, то пропали его результаты.

select session_id, cpu_time, program_name, login_name, database_id 
  from sys.dm_exec_sessions 
 where session_id > 50;

select sum(cpu_time)/1000 as cpu_seconds, database_id 
 from sys.dm_exec_sessions 
group by database_id
order by cpu_seconds desc;

Взгляните на SQL - часовой.Он делает все, что вам нужно, и даже больше.

С уважением, Ливен

Вы смотрели на SQL profiler?

Возьмите стандартный шаблон "T-SQL" или "Хранимая процедура", настройте поля для группировки по идентификатору базы данных (я думаю, вы должны использовать номер, вы не получаете имя базы данных, но это легко узнать, используя exec sp_databases для получения списка)

Запустите это на некоторое время, и вы получите общее количество процессоров / Ввод-вывод с диска / Ожидание и т.д.Это может дать вам долю процессора, используемого каждой базой данных.

Если вы одновременно отслеживаете счетчик PerfMon (регистрируете данные в базе данных SQL) и делаете то же самое для SQL Profiler (регистрируете в базе данных), вы мочь умейте соотносить эти два явления вместе.

Тем не менее, это должно дать вам достаточное представление о том, на какую базу данных стоит обратить более пристальное внимание.Затем проделайте то же самое еще раз только с этим идентификатором базы данных и найдите самые дорогие SQL / хранимые процедуры.

пожалуйста, проверьте этот запрос:

SELECT 
    DB_NAME(st.dbid) AS DatabaseName
    ,OBJECT_SCHEMA_NAME(st.objectid,dbid) AS SchemaName
    ,cp.objtype AS ObjectType
    ,OBJECT_NAME(st.objectid,dbid) AS Objects
    ,MAX(cp.usecounts)AS Total_Execution_count
    ,SUM(qs.total_worker_time) AS Total_CPU_Time
    ,SUM(qs.total_worker_time) / (max(cp.usecounts) * 1.0) AS Avg_CPU_Time 
FROM sys.dm_exec_cached_plans cp 
INNER JOIN sys.dm_exec_query_stats qs 
    ON cp.plan_handle = qs.plan_handle
CROSS APPLY sys.dm_exec_sql_text(cp.plan_handle) st
WHERE DB_NAME(st.dbid) IS NOT NULL
GROUP BY DB_NAME(st.dbid),OBJECT_SCHEMA_NAME(objectid,st.dbid),cp.objtype,OBJECT_NAME(objectid,st.dbid) 
ORDER BY sum(qs.total_worker_time) desc
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top