Измерение эффективности запросов: "Стоимость запроса плана выполнения" против "Время, затраченное",

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

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

  • Есть ли определенный источник, чтобы объяснить, что означает эта мера?

  • Какие еще показатели производительности "Query Performance" используются людьми и каковы их относительные достоинства?


Возможно, важно отметить, что это 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

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

Ответ 1

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

  • Запрос A: процессор с частотой 1,3 секунды, длительность 1.4 сек.
  • Query B: процессор с частотой 2,3 секунды, длительность 1,2 секунды

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

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

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

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

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

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

Ответ 2

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.

Ответ 3

Результаты времени выполнения напрямую противоречат результатам Стоимость запроса, но мне сложно определить, что означает "стоимость запроса".

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

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

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

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

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

Ответ 4

Используйте SET STATISTICS TIME ON

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

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

Ответ 5

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

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

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

Также читайте Когда ищут не искание? Paul White

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

введите описание изображения здесь

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

введите описание изображения здесь

Ответ 6

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

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] 

Вывод запроса будет следующим:

enter image description here

Чтобы оптимизировать стоимость запроса:

Нажмите на свою студию управления SQL

enter image description here

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

enter image description here