【发布时间】: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