Измерение производительности запроса: «Стоимость запроса плана выполнения» против «Времени» - PullRequest
48 голосов
/ 19 февраля 2009

Я пытаюсь определить относительную производительность двух разных запросов, и у меня есть два способа измерения этого:
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%

Результаты времени выполнения прямо противоречат результатам стоимости запроса, но мне трудно определить, что на самом деле означает «стоимость запроса». Мое лучшее предположение состоит в том, что это совокупность операций чтения / записи / CPU_Time / и т. Д., Поэтому у меня есть пара вопросов:

  1. Существует ли конкретный источник, объясняющий, что означает эта мера?

  2. Какие еще метрики "Производительность запроса" используют люди, и каковы их относительные достоинства?


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

EDIT:

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

Stored_Proc    CPU      Reads    Writes   Duration   

test_1a        1313     3975     93       1386
test_1b        2297     49839    93       1207

Впечатляет, что для того, чтобы потреблять больше ресурсов процессора с МНОГИМ большим количеством операций чтения, требуется меньше времени:)

Ответы [ 6 ]

34 голосов
/ 19 февраля 2009

Трассировка профилировщика переводит его в перспективу.

  • Запрос A: 1,3 с ЦП, длительность 1,4 с
  • Запрос B: процессор 2,3 с, длительность 1,2 с

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

Запрос A, вероятно, не является: ЦП <длительность </p>

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

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

Помните, однако, что запрос B использует 100% от 2 CPUS (т.е. 50% для 4 процессоров) в течение одной секунды или около того. Запрос A использует 100% одного процессора в течение 1,5 секунд.

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

12 голосов
/ 07 марта 2011
SET STATISTICS TIME ON

SELECT * 

FROM Production.ProductCostHistory
WHERE StandardCost < 500.00;

SET STATISTICS TIME OFF;

И посмотрите вкладку сообщения, это будет выглядеть так:

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

Результаты времени выполнения прямо противоречат результатам стоимости запроса, но мне трудно определить, что на самом деле означает «стоимость запроса».

Query cost - это то, что оптимизатор думает о том, сколько времени займет ваш запрос (относительно общего времени обработки пакета).

Оптимизатор пытается выбрать оптимальный план запроса, просматривая ваш запрос и статистику ваших данных, пробуя несколько планов выполнения и выбирая наименее дорогостоящий из них.

Здесь вы можете прочитать более подробно о том, как он пытается это сделать.

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

Единственная реальная метрика производительности запроса - это, конечно, сколько времени фактически занимает запрос.

4 голосов
/ 16 августа 2011

Использование SET STATISTICS TIME ON

над вашим запросом.

Ниже рядом с вкладкой результатов вы можете увидеть вкладку сообщений. Там вы можете увидеть время.

2 голосов
/ 03 марта 2016

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

Как вы заметили в вопросе,%, показанный в плане выполнения, не является единственным критерием для определения наилучшего запроса. В следующем примере у меня есть два запроса, выполняющих одну и ту же задачу. План выполнения показывает, что оба одинаково хороши (50% каждый). Теперь я выполнил запросы с SET STATISTICS IO ON, что показывает явные различия.

В следующем примере запрос 1 использует seek, тогда как Query 2 использует scan для таблицы LWManifestOrderLineItems. Однако когда мы действительно проверяем время выполнения, выясняется, что Query 2 работает лучше.

Также прочитайте Когда поиск не является поиском? Пол Уайт

QUERY

---Preparation---------------
-----------------------------
DBCC FREEPROCCACHE
GO
DBCC DROPCLEANBUFFERS
GO

SET STATISTICS IO ON  --IO
SET STATISTICS TIME ON

--------Queries---------------
------------------------------

SELECT LW.Manifest,LW.OrderID,COUNT(DISTINCT LineItemID)
FROM LWManifestOrderLineItems LW
INNER JOIN ManifestContainers MC
    ON MC.Manifest = LW.Manifest
GROUP BY LW.Manifest,LW.OrderID
ORDER BY COUNT(DISTINCT LineItemID) DESC  

SELECT LW.Manifest,LW.OrderID,COUNT( LineItemID) LineCount
FROM LWManifestOrderLineItems LW
WHERE LW.Manifest IN (SELECT Manifest FROM ManifestContainers)
GROUP BY LW.Manifest,LW.OrderID
ORDER BY COUNT( LineItemID) DESC  

Статистика IO

enter image description here

План выполнения

enter image description here

1 голос
/ 24 сентября 2013

Время выполнения запроса:

DECLARE @EndTime datetime
DECLARE @StartTime datetime 
SELECT @StartTime=GETDATE() 


` -- Write Your Query`

SELECT @EndTime=GETDATE()
--This will return execution time of your query
SELECT DATEDIFF(MILLISECOND,@StartTime,@EndTime) AS [Duration in millisecs] 

Query Out Put будет как:

enter image description here

Для оптимизации стоимости запроса:

Нажмите на вашу SQL Management Studio

enter image description here

Запустите ваш запрос и щелкните План выполнения рядом с вкладкой Сообщения вашего результата запроса. вы увидите как

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...