衡量查询性能:“执行计划查询成本”与“所用时间”
Posted
技术标签:
【中文标题】衡量查询性能:“执行计划查询成本”与“所用时间”【英文标题】:Measuring Query Performance : "Execution Plan Query Cost" vs "Time Taken" 【发布时间】:2010-10-08 13:27:45 【问题描述】:我正在尝试确定两个不同查询的相对性能,并且有两种方法可供我测量: 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/etc 的集合,所以我想我有几个问题:
是否有明确的来源来解释此度量的含义?
人们还使用哪些其他“查询性能”指标,它们的相对优点是什么?
需要注意的是,这是一个中型 SQL Server,在 MS Server 2003 Enterprise Edition 上运行 MS SQL Server 2005,具有多个处理器和 100 多个并发用户。
编辑:
经过一番麻烦,我设法获得了对该 SQL Server 的 Profiler 访问权限,并且可以提供额外的信息(它支持与系统资源相关的查询成本,而不是执行时间本身......)
Stored_Proc CPU Reads Writes Duration
test_1a 1313 3975 93 1386
test_1b 2297 49839 93 1207
令人印象深刻的是,通过更多读取占用更多 CPU 需要更少的时间 :)
【问题讨论】:
【参考方案1】:我知道这是一个老问题 - 但是我想添加一个示例,其中成本相同但一个查询比另一个更好。
正如您在问题中观察到的,执行计划中显示的百分比并不是确定最佳查询的唯一标准。在以下示例中,我有两个查询执行相同的任务。执行计划显示两者都一样好(各 50%)。现在我使用SET STATISTICS IO ON
执行查询,这显示出明显的差异。
在以下示例中,查询 1 使用 seek
,而查询 2 使用表 LWManifestOrderLineItems 上的 scan
。然而,当我们实际检查执行时间时,发现查询 2 效果更好。
另请阅读 Paul White 的 When is a Seek not a Seek?
查询
---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
执行计划
【讨论】:
有些人使用DBCC SETCPUWEIGHT(100000000)
(未记录)来检查测试/开发服务器的性能。并记得将其设置回 1,DBCC SETCPUWEIGHT(1) 并释放缓存。
此未记录功能的参考 - sqlblog.com/blogs/paul_white/archive/2010/09/01/…【参考方案2】:
查询执行时间:
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]
查询输出如下:
优化查询成本:
点击您的 SQL 管理工作室
运行您的查询并单击查询结果的消息选项卡旁边的执行计划。你会看到像
【讨论】:
您的代码有错误。您将 NS(纳秒)作为参数传递给 DATEDIFF,但您将结果命名为“以毫秒为单位的持续时间”SELECT DATEDIFF(NS,@StartTime,@EndTime) AS [Duration in millisecs]
应为 SELECT DATEDIFF(MILLISECOND,@StartTime,@EndTime) AS [Duration in millisecs]
【参考方案3】:
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.
【讨论】:
【参考方案4】:使用SET STATISTICS TIME ON
在您的查询之上。
在结果标签附近,您可以看到一个消息标签。在那里你可以看到时间。
【讨论】:
【参考方案5】:分析器跟踪将其置于透视图中。
查询 A:1.3 秒 CPU,1.4 秒持续时间 查询 B:2.3 秒 CPU,1.2 秒持续时间查询 B 正在使用并行度:CPU > 持续时间 例如查询使用 2 个 CPU,平均每个 1.15 秒
查询 A 可能不是:CPU
这解释了相对于批处理的成本:更简单的非并行查询计划的成本为 17%。
优化器计算出查询 B 更昂贵,并且将从并行性中受益,即使这样做需要额外的努力。
但请记住,查询 B 使用 100% 的 2 个 CPU(所以 4 个 CPU 使用 50%)一秒钟左右。查询 A 使用 100% 的单个 CPU 1.5 秒。
查询 A 的峰值较低,但会增加持续时间。 一个用户,谁在乎?有 100 条,也许会有所不同...
【讨论】:
您知道我可以使用哪些资源来了解有关查询评估计划成本的更多信息吗? 本课程是帮助了解查询成本的好资源> youtube.com/playlist?list=PLSE8ODhjZXjbisIGOepfnlbfxeH7TW-8O【参考方案6】:执行时间的结果直接与查询成本的结果相矛盾,但我很难确定“查询成本”的实际含义。
Query cost
是优化器认为您的查询需要多长时间(相对于总批处理时间)。
优化器尝试通过查看您的查询和数据统计信息来选择最佳查询计划,尝试多个执行计划并从中选择成本最低的。
Here 你可以阅读更多关于它如何尝试做到这一点的详细信息。
如您所见,这可能与您实际获得的结果大不相同。
唯一真正的查询性能指标当然是查询实际需要多长时间。
【讨论】:
以上是关于衡量查询性能:“执行计划查询成本”与“所用时间”的主要内容,如果未能解决你的问题,请参考以下文章