Загрузка процессора по базе данных? - PullRequest
30 голосов
/ 26 августа 2008

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

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

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

Ответы [ 8 ]

81 голосов
/ 28 января 2009

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

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 Microsoft представила функции управления производительностью и управления приложениями, которые позволят нам упаковать единую базу данных в распространяемый и развертываемый пакет DAC, и они являются многообещающими функциями, облегчающими управление производительностью отдельных баз данных и их Приложения. Тем не менее, он по-прежнему не делает то, что вы ищете.

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

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

15 голосов
/ 26 августа 2008

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

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

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

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

6 голосов
/ 10 апреля 2012

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

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
1 голос
/ 16 сентября 2016

С учетом всего вышесказанного.
Начиная с 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;
1 голос
/ 04 февраля 2009

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

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

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

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

0 голосов
/ 03 августа 2015

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

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
0 голосов
/ 04 февраля 2009

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

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

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

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

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

0 голосов
/ 04 февраля 2009

Взгляните на SQL Sentry . Делает все что нужно и даже больше.

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

...