0

Измерение производительности запросов: «Стоимость плана выполнения» против «Затраченного времени»

12

Описание проблемы для StackOverflow.com:

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

  1. Запустить оба запроса и измерить время выполнения каждого.
  2. Запустить оба запроса и получить "Стоимость Запроса" из фактического плана выполнения.

Вот код, который я использую для измерения времени выполнения запросов:

DBCC FREEPROCCACHE
GO
DBCC DROPCLEANBUFFERS
GO
DECLARE @start DATETIME SET @start = getDate()
EXEC test_1a
SELECT getDate() - @start AS Execution_Time
GO

DBCC FREEPROCCACHE
GO
DBCC DROPCLEANBUFFERS
GO
DECLARE @start DATETIME SET @start = getDate()
EXEC test_1b
SELECT getDate() - @start AS Execution_Time
GO

Вот что я получаю:

Stored_Proc     Execution_Time     Query Cost (Relative To Batch)

test_1a         1.673 seconds      17%
test_1b         1.033 seconds      83%

Результаты времени выполнения напрямую противоречат результатам Стоимости Запроса, и я испытываю затруднения с пониманием того, что на самом деле означает "Стоимость Запроса". Мой лучший предположение состоит в том, что это агрегат чтений/записей/времени ЦП и т.д. Поэтому у меня есть несколько вопросов:

  1. Существует ли какой-либо достоверный источник, который объясняет, что означает эта мера?
  2. Какие другие метрики "Производительности Запросов" используют люди, и каковы их относительные достоинства?

Важно отметить, что это средний SQL Server, работающий на MS SQL Server 2005 на MS Server 2003 Enterprise Edition с несколькими процессорами и 100+ одновременными пользователями.

Изменение:

После некоторых усилий мне удалось получить доступ к Profiler на этом SQL Server, и я могу предоставить дополнительную информацию (которая подтверждает связь между Стоимостью Запроса и системными ресурсами, а не временем выполнения):

Stored_Proc    CPU      Reads    Writes   Duration   

test_1a        1313     3975     93       1386
test_1b        2297     49839    93       1207

Впечатляет, что использование большего количества ЦП и гораздо большего количества чтений занимает меньше времени 😃

3 ответ(ов)

0

Профайлер дает понимание ситуации.

  • Запрос A: 1.3 секунды CPU, 1.4 секунды продолжительность
  • Запрос B: 2.3 секунды CPU, 1.2 секунды продолжительность

Запрос B использует параллелизм: время CPU > продолжительность, например, запрос использует 2 процессора, в среднем по 1.15 секунды каждый.

Запрос A, вероятно, не использует параллелизм: CPU < продолжительность.

Это объясняет стоимость относительно пакета: 17% для более простого, непараллельного плана запроса.

Оптимизатор определяет, что запрос B более затратный и будет иметь выгоду от параллелизма, даже несмотря на дополнительные затраты на его выполнение.

Однако, стоит помнить, что запрос B использует 100% двух процессоров (то есть 50% для четырех процессоров) в течение примерно одной секунды. Запрос A использует 100% одного процессора в течение 1.5 секунд.

Пиковая нагрузка для запроса A ниже, однако это сказывается на увеличении продолжительности. С одним пользователем это не критично, а вот с 100 пользователями может иметь значение...

0

Для выполнения SQL-запроса, который вы привели, используется команда SET STATISTICS TIME ON, чтобы получить информацию о времени выполнения запроса. В вашем случае запрос извлекает все записи из таблицы Production.ProductCostHistory, где значение StandardCost меньше 500.00.

Такой запрос будет выглядеть следующим образом:

SET STATISTICS TIME ON

SELECT * 

FROM Production.ProductCostHistory
WHERE StandardCost < 500.00;

SET STATISTICS TIME OFF;

После выполнения этого запроса на вкладке "Messages" будет выведена информация о времени выполнения, которая может выглядеть так:

SQL Server Execution Times:

   CPU time = 0 ms,  elapsed time = 10 ms.

(778 row(s) affected)

SQL Server parse and compile time: 

   CPU time = 0 ms, elapsed time = 0 ms.

В этом примере мы видим, что затраты по CPU составили 0 мс, а общее время выполнения запроса — 10 мс. Было затронуто 778 строк, и время анализа и компиляции запроса также составляет 0 мс.

Обратите внимание, что фактические значения времени могут варьироваться в зависимости от нагрузки на сервер и других факторов.

0

Чтобы включить отображение времени выполнения запроса, используйте команду SET STATISTICS TIME ON перед вашим запросом.

После выполнения запроса в окне результатов перейдите на вкладку "Сообщение" (Messages). Там вы сможете увидеть время, затраченное на выполнение вашего запроса.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь