Как проверить, какая хранимая процедура занимает максимальное время на сервере sql

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

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

Можно ли это сделать с помощью SQL-запросов или процедур. У нас есть некоторые процедуры для этого. Любые инструменты SQL или любой внешний инструмент могут быть оплачены (с пробной версией) или бесплатны. Я хочу попробовать их в своей базе данных.

Ответ 1

Вы должны это сделать, используя Dynamic Management Views (DMV), в частности, вас, вероятно, больше всего интересует exec_query_stats, который поддерживает статистику выполнения всех запросов (время процессора, физическое/логическое чтение и т.д.), сгруппированные по плану выполнения.

Также см. эту замечательную статью, которая включает пример запроса для просмотра статистики плана и более подробно описывает тему:

Наконец, если вы хотите трассировать/записывать чрезмерно длинные запросы, тогда вы можете захотеть оставить трассировку профилировщика SQL-сервера в любое время, с фильтром на время выполнения, установленным на некоторые высокий показатель (например, > 1000 мс). Вы можете либо использовать приложение windows-профилировщика SQL-сервера, либо создать трассировку с использованием T-SQL, вместо этого выполните запись в таблицу в базе данных:

Это дает вам возможность точно указать, какой запрос занимал именно то, как долго, когда и какие параметры для этого запроса были (святой SQL Batman!)

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

Еще один трюк, который использовался в прошлом, когда возникали проблемы с производительностью, заключалась в том, чтобы оставить нефильтрованную трассировку сервера SQL в течение короткого периода времени (1 мин или около того) на загруженном SQL-сервере (это действительно имеет удивительно малое влияние, вы просто загружаетесь с журналами)

Я также сердечно рекомендую внутренние компоненты Microsoft SQL Server на эту тему - это очень технично, однако его блестящий, потому что он охватывает не только такие виды диагностических инструментов, но и то, что они на самом деле означают

Ответ 2

Если у вас есть SQL 2005 +, вы можете запускать стандартные отчеты в отчетах управления. Щелкните правой кнопкой мыши по базе данных в студии управления и выберите статистику выполнения объекта - это работает только после последней перезагрузки. Вы также можете запросить, используя DMV sys.dm_exec_query_stats

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

Ответ 3

Вы можете использовать Профайлер SQL Server:

  • Создайте новую трассировку.
  • Выберите нужный сервер
  • Выберите шаблон 'blank'
  • На вкладке "Выбор событий" выберите "SP: завершено" (в разделе "Сохранено" Процедуры)
  • Включите нужные столбцы.
  • В столбце Фильтры выберите Длительность и введите значение "Больше, чем или равным "(обратите внимание на единицы описано выше; это либо миллисекунды или микросекунды). Это ваш "порог"
  • Нажмите "Запустить"

Примечания:

  • Это исключает время загрузки SP; если ваши SP очень большие, что добавить к вышеуказанным временам
  • У меня были проблемы с значение Длительности; если у вас есть проблемы с ним, вы можете захотеть Дата истечения времени начала/начала

Ответ 4

На стороне платного инструмента я настоятельно рекомендую Ignite for SQL Server из Confio Software. Вы можете скачать бесплатную пробную версию и взять ее за спину. Мы использовали его примерно 2 года и очень довольны результатами. В нашем случае мы выбрали несколько хранимых процедур с низким уровнем висячих фруктов, которые мы оптимизировали для быстрых побед только в то время, когда мы запускали демоверсию. Этого было достаточно, чтобы убедить нас, что это стоит инвестиций.

Ответ 5

Это то, что я обычно использую. Я не могу вспомнить, откуда я их получил, но они работают. Это для самых длинных запросов:

SELECT TOP 100
    qs.total_elapsed_time / qs.execution_count / 1000000.0 AS average_seconds,
    qs.total_elapsed_time / 1000000.0 AS total_seconds,
    qs.execution_count,
    SUBSTRING (qt.text,qs.statement_start_offset/2, 
         (CASE WHEN qs.statement_end_offset = -1 
            THEN LEN(CONVERT(NVARCHAR(MAX), qt.text)) * 2 
          ELSE qs.statement_end_offset END - qs.statement_start_offset)/2) AS individual_query,
    o.name AS object_name,
    DB_NAME(qt.dbid) AS database_name
FROM sys.dm_exec_query_stats qs
    CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt
    LEFT OUTER JOIN sys.objects o ON qt.objectid = o.object_id
WHERE qt.dbid = DB_ID()
ORDER BY average_seconds DESC;

... и этот список содержит список запросов с использованием самого ввода-вывода:

SELECT TOP 100
    (total_logical_reads + total_logical_writes) / qs.execution_count AS average_IO,
    (total_logical_reads + total_logical_writes) AS total_IO,
    qs.execution_count AS execution_count,
    SUBSTRING (qt.text,qs.statement_start_offset/2, 
         (CASE WHEN qs.statement_end_offset = -1 
            THEN LEN(CONVERT(NVARCHAR(MAX), qt.text)) * 2 
          ELSE qs.statement_end_offset END - qs.statement_start_offset)/2) AS individual_query,
    o.name AS object_name,
    DB_NAME(qt.dbid) AS database_name
FROM sys.dm_exec_query_stats qs
    CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt
    LEFT OUTER JOIN sys.objects o ON qt.objectid = o.object_id
WHERE qt.dbid = DB_ID()
ORDER BY average_IO DESC;

Надеюсь, что это поможет!

Ответ 6

От выигрывающего ответа на недавний вопрос SO, это даст вам 50 лучших наиболее используемых procs и операторов в procs, Вы можете изменить TOP 50 на TOP 1 или любой другой номер, который вы хотели бы видеть.

SELECT TOP 50 *
FROM ( SELECT COALESCE(OBJECT_NAME(s2.objectid), 'Ad-Hoc') AS ProcName
           ,execution_count
           ,s2.objectid
           ,( SELECT TOP 1 SUBSTRING(s2.text,
                                     statement_start_offset / 2 + 1,
                                     ( ( CASE WHEN statement_end_offset = -1
                                              THEN ( LEN(CONVERT(NVARCHAR(MAX), s2.text))
                                                     * 2 )
                                              ELSE statement_end_offset
                                         END ) - statement_start_offset )
                                     / 2 + 1)
            ) AS sql_statement
           ,last_execution_time
        FROM sys.dm_exec_query_stats AS s1
        CROSS APPLY sys.dm_exec_sql_text(sql_handle) AS s2
     ) x
WHERE sql_statement NOT LIKE 'SELECT * FROM(SELECT coalesce(object_name(s2.objectid)%'
    AND OBJECTPROPERTYEX(x.objectid, 'IsProcedure') = 1
    AND EXISTS ( SELECT 1
                    FROM sys.procedures s
                    WHERE s.is_ms_shipped = 0
                        AND s.name = x.ProcName )
ORDER BY execution_count DESC

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

Ответ 7

Также обратите внимание, что в SQL 2008 для DMC существует новый DMV: sys.dm_exec_procedure_stats. Это представление даст вам совокупную статистику для всей процедуры, включая время и процессор, потраченные на выполнение не связанных с запросом работы, таких как WAITFOR, вызовы функций и условная логика.

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

Еще один инструмент, который вы, возможно, захотите изучить, если вы имеете дело с SQL 2008, - это сборщик данных и хранилище данных управления. Это инструмент, который поставляется с SQL Server (без дополнительных затрат), который позволит вам регулярно собирать статистику запросов и загружать их в хранилище данных. Он поставляется со встроенными сборщиками и отчетами, которые достаточно полны для наиболее общих потребностей мониторинга.

http://msdn.microsoft.com/en-us/library/dd939169(SQL.100).aspx

Из всего сказанного выше, я считаю, что ваш лучший выбор - sys.dm_exec_query_stats, поскольку он имеет низкую накладную, свободную и доступную как на SQL 2005, так и на SQL 2008.

Ответ 8

Если вы использовали SQL Server 2008, вы можете поэкспериментировать с Resource Governor, который позволяет дросселировать и контролировать нагрузку на процессор и память.

В целях ведения журнала вы можете использовать Сбор данных. Вы можете создать набор пользовательских коллекций, который будет собирать снимки из любых DMV и загружать их в хранилище данных производительности.

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