【问题标题】:Why SUM is faster when we are using SMALLINT instead DECIMAL为什么当我们使用 SMALLINT 而不是 DECIMAL 时 SUM 更快
【发布时间】:2014-08-06 11:13:38
【问题描述】:

是否有任何已知规则表明某些 T-SQL 类型更适合计算?

我有两个包含数字的相同表格 - 一个包含 SMALLINT 字段,第二个包含 DECIMAL(9,2) 字段。 我正在对它们执行以下操作(两个查询):

SUM(CAST(A AS BIGINT))
SUM(CAST(A AS BIGINT))
CAST(CAST(SUM(A) AS decimal) / CASE SUM(B) WHEN 0 THEN NULL ELSE SUM(B) END * 100 AS decimal(18, 0))
CAST(CAST(SUM(A) AS decimal) / CASE SUM(B) WHEN 0 THEN NULL ELSE SUM(B) END * 100 AS decimal(18, 1)) 

SUM(CAST(A AS DECIMAL(19,2))) 
SUM(CAST(A AS DECIMAL(19,2)))
CAST(SUM(CAST([A] AS DECIMAL(19, 2))) / IIF(SUM(CAST([B] AS DECIMAL(19, 2))) = 0, NULL, SUM(CAST([B] AS DECIMAL(19, 2)))) * 100 AS DECIMAL(19, 0))
CAST(SUM(CAST([A] AS DECIMAL(19, 2))) / IIF(SUM(CAST([B] AS DECIMAL(19, 2))) = 0, NULL, SUM(CAST([B] AS DECIMAL(19, 2)))) * 100 AS DECIMAL(19, 1))

查询结果如下:

  • 包含小数列的表格需要 29 秒
  • 18 秒用于具有 smallint 列的表

唯一的区别在于每种类型的再见:

这是SMALLINTDECIMAL(9,2) 更快的原因吗?

注意:我在每个表中都有相同的值 - 我没有十进制数 - 只有整数。

【问题讨论】:

  • 我很好奇这个修改的性能:将“CASE SUM(B) WHEN 0 THEN NULL ELSE SUM(B) END”改为:NullIf(SUM(B), 0)
  • @GMastros 需要同样的时间,但我将使用NULLIF 的语法,因为它更适合阅读。

标签: performance tsql sql-server-2012 aggregate-functions sql-types


【解决方案1】:

是的,这是真的。 Smallint 值需要更少的磁盘空间,并且 IO 操作具有更高的性能。尽可能使用“小型”字体总是一个好主意。

【讨论】:

    【解决方案2】:

    来自Microsoft's documentation

    从十进制或数字转换为浮点或实数可能会导致一些精度损失。从 int、smallint、tinyint、float、real、money 或 smallmoney 转换为 decimal 或 numeric 会导致溢出。

    默认情况下,SQL Server 在将数字转换为精度和小数位数较低的小数或数值时使用舍入。但是,如果 SET ARITHABORT 选项为 ON,SQL Server 会在发生溢出时引发错误。仅损失精度和规模不足以引发错误。

    这强烈暗示了围绕decimal 算术的额外操作,特别是缩放、舍入和范围检查。所有这些都比加法更难(计算量更大),尤其是在 x86 CPU 上。

    最快的数据类型是 CPU 原生的数据类型(通常是 charinteger),并且在大多数 SQL 平台上应该是最快的。

    【讨论】:

      猜你喜欢
      • 2021-07-20
      • 1970-01-01
      • 1970-01-01
      • 2013-02-18
      • 1970-01-01
      • 2012-02-21
      • 1970-01-01
      • 1970-01-01
      • 2011-09-30
      相关资源
      最近更新 更多