0

我有一个 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))

提前致谢。

4

1 回答 1

0

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

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

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

  • 构建一个与您的生产表结构相同的测试表,并且
  • 用足够多的随机数据行加载它,它不适合 RAM。

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

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

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

于 2013-05-02T21:53:27.677 回答