如何诊断 try_parse 非常慢?

Rom*_*kov 3 performance sql-server execution-plan sql-server-2012

我有一个非常大的查询,它的运行速度比我想象的要慢,但是对查询执行计划的深入研究并没有帮助揭示这种缓慢。最终我缩小了范围:try_parse是罪魁祸首!

正常查询:

SELECT CloseDate
FROM MyTable

(4959 row(s) affected)

SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 17 ms.
Run Code Online (Sandbox Code Playgroud)

使用 try_parse:

SELECT try_parse(CloseDate as datetime using 'en-us')
FROM MyTable

(4959 row(s) affected)

SQL Server Execution Times:
   CPU time = 719 ms,  elapsed time = 718 ms.
Run Code Online (Sandbox Code Playgroud)

后一种情况下的执行计划看起来很无辜:

在此处输入图片说明

有没有什么方法可以让我以后更容易地发现罪魁祸首?缓慢的实际来源完全隐藏在视线之外。

Mar*_*ith 5

CPU 时间 = 719 毫秒,已用时间 = 718 毫秒。

表明这是 CPU 限制。

如果您可以在开发机器上重现该问题,那么查看 CPU 花费时间的一种方法是使用 Windows 性能记录器。

在跟踪几秒钟后同时运行以下内容......

SET nocount ON;

DECLARE @d DATETIME

WHILE 1 = 1
  SELECT @d = try_parse(NAME AS DATETIMEusing 'en-us')
  FROM   master..spt_values 
Run Code Online (Sandbox Code Playgroud)

... 我明白了(点击进入 embiggen)

在此处输入图片说明

在此期间,SQL Server 占总 CPU 时间的 20.88%。超过 75% 的金额被

SqlAccess.dll!System.Data.SqlServer.Internal.SqlParseIntrinsicImpl::<ParseSsDate>
SqlAccess.dll!System.Data.SqlServer.Internal.SqlAppDomain::ExecuteExtension
Run Code Online (Sandbox Code Playgroud)

随着健康的一部分被占用

clr.dll!IL_Throw
mscorlib.ni.dll!System.DateTimeParse.GetDateTimeParseException(System.DateTimeResult ByRef)
Run Code Online (Sandbox Code Playgroud)

中的所有名称都没有master..spt_values被解析为有效日期,因此最终都返回 null。

上面显示出于某种原因TRY_PARSE调用DateTime.Parse方法并捕获异常,而不是使用TryParse在这种情况下可能表现更好的内置方法。