衡量查询性能:“执行计划查询成本”与“时间”

我试图确定两个不同的查询的相对performance,并有两种方法来衡量这一点对我来说:
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 / etc的集合,所以我想我有几个问题:

  1. 有没有一个明确的来源来解释这个措施的含义?

  2. 还有什么其他的“查询性能”度量标准被人们使用,它们的相对优点是什么?

注意这是一个中等大小的SQL Server,在MS Server 2003 Enterprise Edition上运行带有多个处理器和100多个并发用户的MS SQL Server 2005可能很重要。

编辑:

经过一番打扰之后,我设法在该SQL Server上获得Profiler访问权限,并且可以提供额外的信息(这支持查询成本与系统资源相关,而不是执行时间本身…)

 Stored_Proc CPU Reads Writes Duration test_1a 1313 3975 93 1386 test_1b 2297 49839 93 1207 

令人印象深刻的是,采取更多的CPU与更多的阅读需要更less的时间:)

分析器跟踪将其视为透视。

  • 查询A:1.3秒CPU,1.4秒持续时间
  • 查询B:2.3秒CPU,1.2秒持续时间

查询B使用并行:CPU>持续时间,例如查询使用2个CPU,平均每个1.15秒

查询A可能不是:CPU <持续时间

这说明了与批次相关的成本:简单的非并行查询计划的17%。

优化器计算出查询B更昂贵,并且将从并行中受益,即使这需要额外的努力。

请记住,查询B使用2个CPUS的100%(4个CPU为50%)一秒钟左右。 查询A使用100%的单个CPU 1.5秒。

查询A的峰值较低,代价是持续时间增加。 有一个用户,谁在乎? 有了100,也许会有所作为

 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. 

执行时间的结果直接与查询成本的结果相矛盾,但我很难确定“查询成本”实际上是什么意思。

Query cost是优化器认为查询将花费多长时间(相对于总批处理时间)的因素。

优化器试图通过查看您的数据的查询和统计信息来尝试select最佳的查询计划,尝试多个执行计划并select成本最低的计划。

在这里你可能会更详细地阅读它是如何做到这一点的。

正如你所看到的,这可能与你实际得到的显着不同。

唯一真正的查询性能指标当然是查询实际需要多长时间。

使用SET STATISTICS TIME ON

在您的查询之上。

在靠近结果标签下方,您可以看到一个消息标签。 在那里你可以看到时间。

我知道这是一个老问题 – 但是我想补充一个例子,成本是一样的,但是一个查询比另一个要好。

正如您在问题中所看到的,执行计划中显示的%不是确定最佳查询的唯一标准。 在下面的例子中,我有两个查询执行相同的任务。 执行计划显示两者同样好(每个50%)。 现在我用SET STATISTICS IO ON执行查询,显示明显的差异。

在以下示例中,查询1使用seek而查询2使用表LWManifestOrderLineItems上的scan 。 当我们实际检查执行时间时,发现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

在这里输入图像说明

执行计划

在这里输入图像说明

查询执行时间:

 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 Management Studio

在这里输入图像说明

运行您的查询,然后单击查询结果的消息选项卡旁边的执行计划。 你会看到像

在这里输入图像说明