【问题标题】:Efficiency of Calculating with Different Data Types?不同数据类型的计算效率?
【发布时间】:2013-04-27 02:39:55
【问题描述】:

我有一个 12 亿行数据集,其中包含高精度浮点/十进制数列。我们的要求是精确到小数点后 12 位。我不需要比较完全相等,也不需要防止奇怪的数字伪影(比如 7 出现为 7.000000000000001)。

所以,这个项目可以使用 FLOAT 或 DECIMAL(18,15)... 或者如果有理由可以使用 DECIMAL(15,12)。我需要对这些数据进行的计算涉及 ABS()、AVG()、加法、减法、乘法和除法。可能还有其他统计功能。

如果有的话,哪种数据类型选项对这项任务最有效?

编辑:这是我试图用来回答这个问题的一些测试代码。但我不断收到算术溢出错误。不知道如何在不通过更改数据类型来破坏测试的情况下避免它。有没有人看到我可以投射什么,而不引入使该测试无效的数据类型?代码如下:

IF OBJECT_ID('tempdb..#TempFloat') IS NOT NULL DROP TABLE #TempFloat
IF OBJECT_ID('tempdb..#TempDecimal') IS NOT NULL DROP TABLE #TempDecimal
IF OBJECT_ID('tempdb..#TempBinary') IS NOT NULL DROP TABLE #TempBinary

SELECT CAST(RAND() AS FLOAT) AS RandA, CAST(0 AS FLOAT) AS CalcA INTO #TempFloat 
SELECT CAST(RAND() AS DECIMAL(18,15)) AS RandA, CAST(0 AS DECIMAL(18,15)) AS CalcA INTO #TempDecimal
SELECT CAST(RAND() AS BINARY(8)) AS RandA, CAST(0 AS BINARY(8)) AS CalcA INTO #TempBinary

INSERT INTO #TempFloat
(
    RandA,
    CalcA
)
(
SELECT 
    CAST(RAND() AS FLOAT) AS RandA, 
    CAST(0 AS FLOAT) AS CalcA
)

INSERT INTO #TempDecimal
(
    RandA,
    CalcA
)
(
SELECT 
    CAST(RAND() AS FLOAT) AS RandA, 
    CAST(0 AS FLOAT) AS CalcA
)

INSERT INTO #TempBinary
(
    RandA,
    CalcA
)
(
SELECT 
    CAST(RAND() AS FLOAT) AS RandA, 
    CAST(0 AS FLOAT) AS CalcA
)
GO  -- 9999

UPDATE #TempFloat
SET CalcA = (ABS((RandA/2) - 1) * 10000) + (RandA - (RandA * 2))

UPDATE #TempDecimal
SET CalcA = (ABS((RandA/2) - 1) * 10000) + (RandA - (RandA * 2))

UPDATE #TempBinary
SET CalcA = (ABS((RandA/2) - 1) * 10000) + (RandA - (RandA * 2))

提前致谢。

【问题讨论】:

  • 为什么不尝试几种不同的方法来衡量性能呢? (当然,在数据的一个子集上。)我怀疑这将归结为两个主要因素 1)特定的 RDBMS(应该包含在标签中); 2) RDBMS 能够使用本机浮点运算而无需中间保护或转换
  • 传入的数据类型是什么?我通常会匹配。
  • 数据集必须是人类可读的吗?没有人会阅读 10^9 的数字。如果是双精度二进制形式,每个数字占8个字节,读取数据为硬件速度,全17位精度。
  • 您多久进行一次计算而不是读取数据?对于大多数 SQL 查询,读取和写入页面的开销远远超过了数值处理方面的考虑。
  • @user2246674,我已经尝试测试 FLOAT、DECIMAL 和 BINARY(8)。我的测试代码和实现它的问题现在在上面的帖子中。

标签: sql performance sql-server-2005 optimization types


【解决方案1】:

根据经验,双精度数的计算速度比数字或小数的计算速度要快。任意精度的数学是昂贵的。现代计算机上的浮点数学相对便宜。 (是否只有我记得必须购买浮点处理器来加速电子表格计算?)

但这是经验法则。如果您的数字或小数类型中有很多行、很多列,并且相对位数很少,那么您可能会发现磁盘 I/O 是瓶颈。 (PostgreSQL 在数字数据类型中支持多达 1000 位的精度。我称之为相对 many 位。)

你能为你的公司做的最好的事情就是

  • 构建一个与您的生产表结构相同的测试表,然后
  • 用足够多的随机数据行加载它,它无法放入 RAM。

然后运行一组查询并计时以测试性能。

使用与生产环境相同的测试表,因为列多与列少对磁盘子系统的影响不同。使用 lot 的随机数据,因为您想尝试逼近麻烦表的行为。 (使用窄表进行测试,就像您在测试代码中所做的那样,不会对系统造成足够的压力。)

如果此表在财务上很重要,那么可能值得阅读您的 dbms 文档以了解 CREATE TABLE 语句。您几乎肯定会发现几个可以显着影响性能的选项。 Oracle 的 CREATE TABLE 语句文档在纸上打印大约需要 50 页。 (50,不是错字。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-05
    • 2019-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-08
    相关资源
    最近更新 更多