Подтвердить что ты не робот

Загрузка процессора по базе данных?

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

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

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

4b9b3361

Ответ 1

Сорт. Проверьте этот запрос:

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

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

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

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

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

Ухудшается, когда вы:

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

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

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

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

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

Ответ 2

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

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

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

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

Ответ 3

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

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

Ответ 4

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

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

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

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

Ответ 5

Учитывая все сказанное выше.
Начиная с SQL Server 2012 (может быть, 2008?), Есть столбец database_id в sys.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;

Ответ 6

Посмотрите SQL Sentry. Он делает все, что вам нужно, и многое другое.

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

Ответ 7

Посмотрели ли вы на профилировщик SQL?

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

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

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

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

Ответ 8

проверьте этот запрос:

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