Sql h2默认十进制精度性能

Sql h2默认十进制精度性能,sql,precision,h2,database-performance,Sql,Precision,H2,Database Performance,当我使用默认精度设置创建DECIMAL列时,在H2 web控制台中,此列被定义为DECIMAL(65535332767),命令“show columns from…”给出DECIMAL(65535) H2中的十进制数据类型映射到BigDecimal(来自H2文档),但我不确定H2如何处理它 如果我使用更小的精度,是否有性能提升?要了解更多关于H2的DECIMAL数据类型,请查看H2-x.y.z.jar附带的org.H2.value.ValueDecimal类 仔细观察,您将看到默认值如您所述:

当我使用默认精度设置创建
DECIMAL
列时,在H2 web控制台中,此列被定义为
DECIMAL(65535332767)
,命令“show columns from…”给出
DECIMAL(65535)

H2中的十进制数据类型映射到
BigDecimal
(来自H2文档),但我不确定H2如何处理它


如果我使用更小的精度,是否有性能提升?

要了解更多关于H2的
DECIMAL
数据类型,请查看
H2-x.y.z.jar
附带的
org.H2.value.ValueDecimal

仔细观察,您将看到默认值如您所述:

/** The default precision for a decimal value. */
static final int DEFAULT_PRECISION = 65535;
/** The default scale for a decimal value.     */
static final int DEFAULT_SCALE = 32767;
仔细查看
ValueDecimal

private final BigDecimal value;
org.h2.store.Data

public Value readValue() {
    ...
    case Value.DECIMAL: {
        int scale = readVarInt();
        int len = readVarInt();
        byte[] buff = DataUtils.newBytes(len);
        read(buff, 0, len);
        BigInteger b = new BigInteger(buff);
        return ValueDecimal.get(new BigDecimal(b, scale));
    }
您可以看到,
DECIMAL
只不过是一个
BigDecimal
。也就是说,使用
java.math.BigDecimal
将面临所有性能问题,而使用
DECIMAL
将面临所有性能问题

如果你真的对它感兴趣,你可以进一步研究这门课,看看精密度/刻度的确切作用

如果我们看文档,所有关于
DECIMAL
数据类型和性能的说明都是:

REAL
DOUBLE
类型相比,
DECIMAL
/
NUMERIC
类型速度较慢,需要更多的存储空间

所以他们说这是事实

但既然你在谈论性能,我们可以切入正题,做一些测试。测试类的代码如下,让我们来看看输出/结果:

TYPE              INSERT time    COUNT() time   .db Size (kb)  
DECIMAL(20,2)     6.978          0.488          27958.0        
DECIMAL(100,2)    4.879          0.407          25648.0        
DECIMAL(100,80)   8.794          0.868          90818.0        
DECIMAL(60000,2)  4.388          0.4            25104.0        
DECIMAL(1000,900) 112.905        6.549          1016534.0      
REAL              5.938          0.318          22608.0        
DOUBLE            6.985          0.416          25088.0    
如您所见,当精度发生变化时,时间或存储大小没有明显变化(精度
20
所需的时间/大小大约与
60000
!)相同

问题是当您更改比例时。这是你应该担心的;如您所见,
DECIMAL(100,2)
DECIMAL(100,80)
在时间和存储方面都有很大的增加

DECIMAL(1000900)
存储绝对相同的值所需的时间超过1G(!!!)

最后,在上面的测试中,
REAL
DOUBLE
似乎并不比
DECIMAL
好多少(它们可能更糟)。但是试着改变插入的行数(测试方法中的
for
循环),行数越大,响应越好

*
DECIMAL(20,2)
似乎比其余部分慢/大。那不是真的。实际上,无论您选择先运行什么,都会稍微慢一点/大一点。想想看

公共类主{
公共静态void main(字符串[]a)引发异常{
Class.forName(“org.h2.Driver”);
System.out.format(“%-18s%-15s%-15s%-15s”,“TYPE”,“INSERT time”,“COUNT()time”,“.db Size(kb)”);
System.out.println();
测试性能(“测试十进制数”、“十进制数(20,2)”;
测试性能(“测试十进制数”、“十进制数(100,2)”;
测试性能(“测试十进制数”、“十进制数(100,80)”;
testPerformance(“TEST_DECIMAL_60000_2”,“DECIMAL(60000,2)”);
测试性能(“测试十进制数”、“十进制数(1000900)”;
testPerformance(“TEST_REAL”、“REAL”);
测试性能(“双重测试”、“双重测试”);
}
私有静态void testPerformance(字符串dbName,字符串类型)引发SQLException{
系统输出格式(“%-18s”,类型);
连接conn=DriverManager.getConnection(“jdbc:h2:”+dbName,“sa”,”);
conn.createStatement().execute(“如果存在测试,则删除表;”);
conn.createStatement().execute(“创建表测试(DECTEST“+type+”));
long insertStartTime=System.currentTimeMillis();
对于(int i=0;i<1000000;i++){
conn.createStatement().execute(“插入测试(DECTEST)值(12345678901344.45)”;
}
double insertTime=((double)(System.currentTimeMillis()-insertStartTime))/1000;
System.out.format(“%-15s”,insertTime+”);
long countStartTime=System.currentTimeMillis();
conn.createStatement().executeQuery(“从测试中选择计数(DECTEST));
double countTime=((double)(System.currentTimeMillis()-countStartTime))/1000;
System.out.format(“%-15s”,countTime+”);
康涅狄格州关闭();
double fileSize=(double)新文件(dbName+“.h2.db”).length()/1024;
System.out.format(“%-15s”,文件大小+”);
System.out.println();
}
}

小数的精度和刻度在H2中是可选的。如果在不指定精度/比例的情况下创建列,则性能不受影响,存储不受影响,并且可以插入任何值,并将返回相同的值:

create table test(data decimal);
insert into test values(1.345);
select * from test;
> 1.345

你真的需要65535个整数和32767个分数吗?这就是你在这份声明中的意图吗?
create table test(data decimal);
insert into test values(1.345);
select * from test;
> 1.345