TRY_PARSE,但速度更快

时间:2019-02-27 15:38:03

标签: sql-server sql-server-2012 data-conversion

将大量(近100个)nvarchar列转换为浮点数的最快方法是什么?

目前,我有一堆TRY_PARSE(列名为FLOAT)语句,每列一个。

在列不解析为浮动的情况下,我想要NULL。没有错误通知,没有额外的情报。

有更快的方法吗?如果是这样,那会是什么?

SQL Server 2012

3 个答案:

答案 0 :(得分:4)

只是一个简短的测试,以显示TRY_PARSETRY_CAST之间的性能差异

我的结果

  • TRY_CAST 327毫秒
  • TRY_PARSE 17784毫秒

这意味着TRY_CASTTRY_PARSE快50倍(顺便说一句:TRY_CONVERT的性能几乎与TRY_CAST相同)。

尝试一下并发布结果;-)

SET LANGUAGE ENGLISH;

DECLARE @tbl TABLE(SomeFloatAsString VARCHAR(100),fl2 VARCHAR(100),fl3 VARCHAR(100),fl4 VARCHAR(100),fl5 VARCHAR(100),fl6 VARCHAR(100),fl7 VARCHAR(100),fl8 VARCHAR(100),fl9 VARCHAR(100),fl10 VARCHAR(100));
DECLARE @i INT=0;
WHILE @i<100000
BEGIN
    INSERT INTO @tbl VALUES(RAND(),RAND(),RAND(),RAND(),RAND(),RAND(),RAND(),RAND(),RAND(),RAND());
    SET @i+=1;
END

DECLARE @d DATETIME2 = SYSUTCDATETIME();

SELECT TRY_CAST(SomeFloatAsString AS FLOAT) fl1
      ,TRY_CAST(fl2 AS FLOAT) fl2
      ,TRY_CAST(fl3 AS FLOAT) fl3
      ,TRY_CAST(fl4 AS FLOAT) fl4
      ,TRY_CAST(fl5 AS FLOAT) fl5
      ,TRY_CAST(fl6 AS FLOAT) fl6
      ,TRY_CAST(fl7 AS FLOAT) fl7
      ,TRY_CAST(fl8 AS FLOAT) fl8
      ,TRY_CAST(fl9 AS FLOAT) fl9
      ,TRY_CAST(fl10 AS FLOAT)fl10
INTO #tmp1
FROM @tbl

SELECT DATEDIFF(MILLISECOND,@d,SYSUTCDATETIME())


DECLARE @d2 DATETIME2 = SYSUTCDATETIME();

SELECT TRY_PARSE(SomeFloatAsString AS FLOAT) fl1
      ,TRY_PARSE(fl2 AS FLOAT) fl2 
      ,TRY_PARSE(fl3 AS FLOAT) fl3
      ,TRY_PARSE(fl4 AS FLOAT) fl4
      ,TRY_PARSE(fl5 AS FLOAT) fl5
      ,TRY_PARSE(fl6 AS FLOAT) fl6
      ,TRY_PARSE(fl7 AS FLOAT) fl7
      ,TRY_PARSE(fl8 AS FLOAT) fl8
      ,TRY_PARSE(fl9 AS FLOAT) fl9
      ,TRY_PARSE(fl10 AS FLOAT)fl10
INTO #tmp2
FROM @tbl

SELECT DATEDIFF(MILLISECOND,@d2,SYSUTCDATETIME());

答案 1 :(得分:2)

不幸的是,通常的答案是,如果用户需要使用特定区域性解析的字段,则不能用TRY_CAST或TRY_CONVERT替换TRY_PARSE。

如果您要进行简单,直接的转换,例如“ ... AS INT”,请使用TRY_CAST或TRY_CONVERT。如果您需要翻译文化,则必须坚持TRY_PARSE。

答案 2 :(得分:0)

Shnugo认为TRY_CAST应该更快,所以我认为有什么比测试更好的方法了,我同意从“快速”测试中达成共识。

首先,进行简短的设置以创建一些数据:

USE Sandbox;
GO

DECLARE @SQL nvarchar(MAX);
CREATE TABLE TallyTable (I int);
WITH N AS(
    SELECT N
    FROM (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL)) N(N)),
Tally AS(
    SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS I
    FROM N N1
         CROSS JOIN N N2
         CROSS JOIN N N3)
INSERT INTO dbo.TallyTable (I)
SELECT I
FROM Tally;

SELECT @SQL =
       N'CREATE TABLE SampleTable (' + 
       STUFF((SELECT TOP 100
                     N',' + NCHAR(10) + 
                     N'    ' + QUOTENAME(CONCAT(N'Col',T.I)) + N' varchar(10)'
              FROM TallyTable T
              FOR XML PATH(N'')),1,1,N'') + NCHAR(10) + N');';
EXEC sp_executesql @SQL;
SELECT @SQL =
      N'INSERT INTO SampleTable' + NCHAR(10) + 
      N'VALUES(' + STUFF((SELECT TOP 100 ',0'
                          FROM TallyTable T
                          FOR XML PATH(N'')),1,1,N'') + N');';

EXEC sp_executesql @SQL;
GO

这将创建一个表,该表包含100列,值为“ 0”。现在,如果我们尝试TRY_CASTTRY_PARSE

SET STATISTICS TIME ON;

PRINT 'TRY_PARSE';

SELECT TRY_PARSE(Col1 AS float),
       TRY_PARSE(Col2 AS float),
       TRY_PARSE(Col3 AS float),
       TRY_PARSE(Col4 AS float),
       TRY_PARSE(Col5 AS float),
       TRY_PARSE(Col6 AS float),
       TRY_PARSE(Col7 AS float),
       TRY_PARSE(Col8 AS float),
       TRY_PARSE(Col9 AS float),
       TRY_PARSE(Col10 AS float),
       TRY_PARSE(Col11 AS float),
       TRY_PARSE(Col12 AS float),
       TRY_PARSE(Col13 AS float),
       TRY_PARSE(Col14 AS float),
       TRY_PARSE(Col15 AS float),
       TRY_PARSE(Col16 AS float),
       TRY_PARSE(Col17 AS float),
       TRY_PARSE(Col18 AS float),
       TRY_PARSE(Col19 AS float),
       TRY_PARSE(Col20 AS float),
       TRY_PARSE(Col21 AS float),
       TRY_PARSE(Col22 AS float),
       TRY_PARSE(Col23 AS float),
       TRY_PARSE(Col24 AS float),
       TRY_PARSE(Col25 AS float),
       TRY_PARSE(Col26 AS float),
       TRY_PARSE(Col27 AS float),
       TRY_PARSE(Col28 AS float),
       TRY_PARSE(Col29 AS float),
       TRY_PARSE(Col30 AS float),
       TRY_PARSE(Col31 AS float),
       TRY_PARSE(Col32 AS float),
       TRY_PARSE(Col33 AS float),
       TRY_PARSE(Col34 AS float),
       TRY_PARSE(Col35 AS float),
       TRY_PARSE(Col36 AS float),
       TRY_PARSE(Col37 AS float),
       TRY_PARSE(Col38 AS float),
       TRY_PARSE(Col39 AS float),
       TRY_PARSE(Col40 AS float),
       TRY_PARSE(Col41 AS float),
       TRY_PARSE(Col42 AS float),
       TRY_PARSE(Col43 AS float),
       TRY_PARSE(Col44 AS float),
       TRY_PARSE(Col45 AS float),
       TRY_PARSE(Col46 AS float),
       TRY_PARSE(Col47 AS float),
       TRY_PARSE(Col48 AS float),
       TRY_PARSE(Col49 AS float),
       TRY_PARSE(Col50 AS float),
       TRY_PARSE(Col51 AS float),
       TRY_PARSE(Col52 AS float),
       TRY_PARSE(Col53 AS float),
       TRY_PARSE(Col54 AS float),
       TRY_PARSE(Col55 AS float),
       TRY_PARSE(Col56 AS float),
       TRY_PARSE(Col57 AS float),
       TRY_PARSE(Col58 AS float),
       TRY_PARSE(Col59 AS float),
       TRY_PARSE(Col60 AS float),
       TRY_PARSE(Col61 AS float),
       TRY_PARSE(Col62 AS float),
       TRY_PARSE(Col63 AS float),
       TRY_PARSE(Col64 AS float),
       TRY_PARSE(Col65 AS float),
       TRY_PARSE(Col66 AS float),
       TRY_PARSE(Col67 AS float),
       TRY_PARSE(Col68 AS float),
       TRY_PARSE(Col69 AS float),
       TRY_PARSE(Col70 AS float),
       TRY_PARSE(Col71 AS float),
       TRY_PARSE(Col72 AS float),
       TRY_PARSE(Col73 AS float),
       TRY_PARSE(Col74 AS float),
       TRY_PARSE(Col75 AS float),
       TRY_PARSE(Col76 AS float),
       TRY_PARSE(Col77 AS float),
       TRY_PARSE(Col78 AS float),
       TRY_PARSE(Col79 AS float),
       TRY_PARSE(Col80 AS float),
       TRY_PARSE(Col81 AS float),
       TRY_PARSE(Col82 AS float),
       TRY_PARSE(Col83 AS float),
       TRY_PARSE(Col84 AS float),
       TRY_PARSE(Col85 AS float),
       TRY_PARSE(Col86 AS float),
       TRY_PARSE(Col87 AS float),
       TRY_PARSE(Col88 AS float),
       TRY_PARSE(Col89 AS float),
       TRY_PARSE(Col90 AS float),
       TRY_PARSE(Col91 AS float),
       TRY_PARSE(Col92 AS float),
       TRY_PARSE(Col93 AS float),
       TRY_PARSE(Col94 AS float),
       TRY_PARSE(Col95 AS float),
       TRY_PARSE(Col96 AS float),
       TRY_PARSE(Col97 AS float),
       TRY_PARSE(Col98 AS float),
       TRY_PARSE(Col99 AS float),
       TRY_PARSE(Col100 AS float)
FROM dbo.SampleTable;

PRINT 'TRY_CAST';

SELECT TRY_CAST(Col1 AS float),
       TRY_CAST(Col2 AS float),
       TRY_CAST(Col3 AS float),
       TRY_CAST(Col4 AS float),
       TRY_CAST(Col5 AS float),
       TRY_CAST(Col6 AS float),
       TRY_CAST(Col7 AS float),
       TRY_CAST(Col8 AS float),
       TRY_CAST(Col9 AS float),
       TRY_CAST(Col10 AS float),
       TRY_CAST(Col11 AS float),
       TRY_CAST(Col12 AS float),
       TRY_CAST(Col13 AS float),
       TRY_CAST(Col14 AS float),
       TRY_CAST(Col15 AS float),
       TRY_CAST(Col16 AS float),
       TRY_CAST(Col17 AS float),
       TRY_CAST(Col18 AS float),
       TRY_CAST(Col19 AS float),
       TRY_CAST(Col20 AS float),
       TRY_CAST(Col21 AS float),
       TRY_CAST(Col22 AS float),
       TRY_CAST(Col23 AS float),
       TRY_CAST(Col24 AS float),
       TRY_CAST(Col25 AS float),
       TRY_CAST(Col26 AS float),
       TRY_CAST(Col27 AS float),
       TRY_CAST(Col28 AS float),
       TRY_CAST(Col29 AS float),
       TRY_CAST(Col30 AS float),
       TRY_CAST(Col31 AS float),
       TRY_CAST(Col32 AS float),
       TRY_CAST(Col33 AS float),
       TRY_CAST(Col34 AS float),
       TRY_CAST(Col35 AS float),
       TRY_CAST(Col36 AS float),
       TRY_CAST(Col37 AS float),
       TRY_CAST(Col38 AS float),
       TRY_CAST(Col39 AS float),
       TRY_CAST(Col40 AS float),
       TRY_CAST(Col41 AS float),
       TRY_CAST(Col42 AS float),
       TRY_CAST(Col43 AS float),
       TRY_CAST(Col44 AS float),
       TRY_CAST(Col45 AS float),
       TRY_CAST(Col46 AS float),
       TRY_CAST(Col47 AS float),
       TRY_CAST(Col48 AS float),
       TRY_CAST(Col49 AS float),
       TRY_CAST(Col50 AS float),
       TRY_CAST(Col51 AS float),
       TRY_CAST(Col52 AS float),
       TRY_CAST(Col53 AS float),
       TRY_CAST(Col54 AS float),
       TRY_CAST(Col55 AS float),
       TRY_CAST(Col56 AS float),
       TRY_CAST(Col57 AS float),
       TRY_CAST(Col58 AS float),
       TRY_CAST(Col59 AS float),
       TRY_CAST(Col60 AS float),
       TRY_CAST(Col61 AS float),
       TRY_CAST(Col62 AS float),
       TRY_CAST(Col63 AS float),
       TRY_CAST(Col64 AS float),
       TRY_CAST(Col65 AS float),
       TRY_CAST(Col66 AS float),
       TRY_CAST(Col67 AS float),
       TRY_CAST(Col68 AS float),
       TRY_CAST(Col69 AS float),
       TRY_CAST(Col70 AS float),
       TRY_CAST(Col71 AS float),
       TRY_CAST(Col72 AS float),
       TRY_CAST(Col73 AS float),
       TRY_CAST(Col74 AS float),
       TRY_CAST(Col75 AS float),
       TRY_CAST(Col76 AS float),
       TRY_CAST(Col77 AS float),
       TRY_CAST(Col78 AS float),
       TRY_CAST(Col79 AS float),
       TRY_CAST(Col80 AS float),
       TRY_CAST(Col81 AS float),
       TRY_CAST(Col82 AS float),
       TRY_CAST(Col83 AS float),
       TRY_CAST(Col84 AS float),
       TRY_CAST(Col85 AS float),
       TRY_CAST(Col86 AS float),
       TRY_CAST(Col87 AS float),
       TRY_CAST(Col88 AS float),
       TRY_CAST(Col89 AS float),
       TRY_CAST(Col90 AS float),
       TRY_CAST(Col91 AS float),
       TRY_CAST(Col92 AS float),
       TRY_CAST(Col93 AS float),
       TRY_CAST(Col94 AS float),
       TRY_CAST(Col95 AS float),
       TRY_CAST(Col96 AS float),
       TRY_CAST(Col97 AS float),
       TRY_CAST(Col98 AS float),
       TRY_CAST(Col99 AS float),
       TRY_CAST(Col100 AS float)
FROM dbo.SampleTable;

SET STATISTICS TIME OFF;

上面的结果是微不足道的,但仍然显示:

TRY_PARSE

 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.

(1 row affected)

 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 4 ms.
TRY_CAST

 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.

(1 row affected)

 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.

与100列的1行相比,相差4毫秒。然后让我们调高音量(这需要一段时间才能运行):

DECLARE @SQL nvarchar(MAX);
SELECT @SQL =
      N'INSERT INTO SampleTable' + NCHAR(10) + 
      N'VALUES' +STUFF((SELECT N',' + NCHAR(10) +
      N'       (' + STUFF((SELECT TOP 100 ',0'
                                              FROM TallyTable T
                                              FOR XML PATH(N'')),1,1,N'') + N')'
                        FROM TallyTable T
                        FOR XML PATH(N'')),1,1,N'') + N';';

SELECT @SQL;
EXEC sp_executesql @SQL;
EXEC sp_executesql @SQL;
EXEC sp_executesql @SQL;
EXEC sp_executesql @SQL;
EXEC sp_executesql @SQL;
--Now we have 5001 rows

现在我们有5,001行和100列。现在,如果我们再次执行以上操作……

TRY_PARSE

 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.

(5001 rows affected)

 SQL Server Execution Times:
   CPU time = 14672 ms,  elapsed time = 18690 ms.
TRY_CAST

 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.

(5001 rows affected)

 SQL Server Execution Times:
   CPU time = 125 ms,  elapsed time = 671 ms.

相差18019毫秒(相当于18秒,快了将近28倍!)。

因此,答案是使用TRY_CAST(或TRY_CONVERT,我相信它会很快)。

--cleanup
DROP TABLE dbo.TallyTable;
DROP TABLE SampleTable;