在公司的测试服务器上进行测试,分别测试两个数据库在BIGINT和DECIMAL时的性能。
因为听说一些线上系统在存储金额的时候,在系统内部会把金额转成整数然后进行运算,而且我也想看看两种数据库在纯运算上有多大差距。
硬件环境:
CPU:志强 E5 2603 1.7GHz(给此虚拟机分配了2个核)
内存:4GB
软件环境:
Windows 2008 R2 Standard Service Pack 1
MySQL v5.7.23
PostgresSQL v14.1
测试脚本的功能:根据传参,将入参n与预定的数相加m次,为防止缓存与编译优化,预定的数为循环变量x,最后输出。
MySQL:
DROP FUNCTION if exists fun_bigint_add;
CREATE FUNCTION fun_bigint_add(n bigint, m bigint)
RETURNS bigint
no sql
BEGIN
declare i bigint;
declare x bigint; -- 循环变量
set x = 1;
set i = n;
while x<=m do
set i = i + x;
set x = x + 1;
end while;
return i;
END;
DROP FUNCTION if exists fun_decimal_add;
CREATE FUNCTION fun_decimal_add(n DECIMAL(40,8), m DECIMAL(40,8))
RETURNS DECIMAL(40,8)
no sql
BEGIN
declare i DECIMAL;
declare x DECIMAL; -- 循环变量
set x = 1;
set i = n;
while x<=m do
set i = i + (x/10000);
set x = x + 1;
end while;
return i;
END;
PgSQL:
CREATE OR REPLACE FUNCTION fun_bigint_add(n bigint, m bigint)
RETURNS bigint
AS $BODY$
declare i bigint;
declare x bigint; -- 循环变量
BEGIN
x := 1;
i := n;
while x<=m loop
i := i + x;
x := x + 1;
end loop;
return i;
END;
$BODY$
LANGUAGE plpgsql VOLATILE;
CREATE OR REPLACE FUNCTION fun_decimal_add(n decimal(40,8), m decimal(40,8))
RETURNS decimal(40,8)
AS $BODY$
declare i decimal;
declare x decimal; -- 循环变量
BEGIN
x := 1;
i := n;
while x<=m loop
i := i + (x/10000);
x := x + 1;
end loop;
return i;
END;
$BODY$
LANGUAGE plpgsql VOLATILE;
执行工具与方式,本机使用Navicat远程连接那台测试服务器,执行测试脚本。
测试服务器当前为闲置状态,只有我的脚本在运行,即不存在其他的程序争抢资源。
测试结果:
MySQL:
SELECT fun_bigint_add(9000000000000011, 10000001); -- 耗时754秒
SELECT fun_decimal_add(9000000000000.01155, 10000001); -- 耗时840秒
PgSQL:
SELECT fun_bigint_add(9000000000000011, 10000001); -- 三次分别耗时,4.120秒、4.421秒、3.976秒
SELECT fun_decimal_add(9000000000000.011555, 10000001); -- 三次分别耗时,15.810秒、17.697秒、14.993秒
虽然没有对两个数据库做深入的调优,且MySQL也只是用5.7而不是MySQL8,不过,看样子两种数据库的在计算上的差距远远不是调一下参数就能赶超的。
后面有机会,我再搞点测试数据,试一下实际业务中的加减和sum等运算,模拟计算某人账单金额之类的。
结论:
1、BIGINT性能确实比DECIMAL好一些,大型、超大型系统确实应该考虑使用BIGINT来做为金额使用,不过要小心溢出或最终变成DECIMAL的整数。
2、不要在MySQL中做计算,不要在MySQL中做计算,不要在MySQL中做计算,重要的事情说3遍!!!
3、必要的情况下,特别是开发业务系统,需要进行各种基础计算的情况下,还是应该优先考虑PgSQL,而不是MySQL。