[导读]数据库JDBC有多慢JAVA应用必须通过JDBC从数据库中取数,有时候我们会发现,数据库的负担一点也不重而且SQL很简单,但取数的速度仍然很慢。我们来实际测试一下,有个感性认识,以Oracle为例。数据来源使用TPCH生成的数据,选用其中的customer表来做测试,数据记录为1...
数据库JDBC有多慢JAVA 应用必须通过 JDBC 从数据库中取数,有时候我们会发现,数据库的负担一点也不重而且 SQL 很简单,但取数的速度仍然很慢。我们来实际测试一下,有个感性认识,以Oracle为例。数据来源使用TPCH生成的数据,选用其中的customer表来做测试,数据记录为1500万行,8个字段。它生成的原始文本文件名为customer.tbl,文件大小为2.3G。利用数据库提供的数据导入工具将此文件数据导入到Oracle的数据表中。测试环境CPU:2颗Intel3014,主频1.7G,每个CPU内核数6个。硬盘(SSD):1T 561MB/s(读) 523MB/s(写) 接口:SATA 6.0Gb/s内存:64G。操作系统:Linux CentOS 7所有测试均在服务器本机上完成,没有消耗网络传输时间。数据库读数测试通过Oracle提供的JDBC接口,用SQL语句执行数据读取。Java写起来麻烦,用SPL脚本执行测试:
|
A
|
B
|
1
|
=now()
|
/记录时间
|
2
|
=connect("oracle")
|
/连接数据库
|
3
|
=A2.cursor("SELECT * FROM CUSTOMER")
|
/生成取数游标
|
4
|
for A3,10000
|
/循环取数,每次10000条
|
5
|
=A2.close()
|
/关闭连接
|
6
|
=interval@s(A1,now())
|
/计算时长
|
测试结果:275秒文本文件对比测试只从上面的测试结果来看,还没有太多感性认识,我们再读一下文本文件来对比。办法是一样的,从文件中读出数据,并解析出记录,不作任何计算。编写如下SPL脚本执行测试:
|
A
|
B
|
1
|
=now()
|
/记录时间
|
2
|
=file("customer.tbl")
|
/文件对象
|
3
|
=A2.cursor(;,"|")
|
/生成取数游标,分隔符是|
|
4
|
for A3,10000
|
/循环取数,每次10000条
|
5
|
=interval@s(A1,now())
|
/计算时长
|
测试结果:43秒这意味着,读取文本要比读取Oracle快275/43=6.4倍。我们知道,文本解析是个非常麻烦的事情,但即使这样,从文本文件读取数据还是远远快于从数据库中读数。
利用集算器 SPL并行提速当数据只能从数据库读取,而且数据库本身负担并不重时,我们可以利用多 CPU 并行方案来提速,但写Java 的并行程序非常麻烦,要考虑资源共享冲突等问题。使用集算器SPL的并行技术可以提升数据库JDBC取数性能,避免 JAVA 硬编码的复杂性,方便实现多线程结果集的合并。下面我们来测试一下。单表并行取数还是上面的这张customer表 ,改为并行取数后,可以看到性能提升明显,代码如下:
|
A
|
B
|
1
|
=now()
|
/记录时间
|
2
|
=connect("oracle").query@ix("SELECT COUNT(*) FROM CUSTOMER")(1)
|
3
|
>n=12
|
/并行数
|
4
|
=n.([int(A2/n)*(~-1),int(A2/n)*~])
|
/按并行数分段区间
|
5
|
fork A4
|
=connect("oracle")
|
6
|
|
=B5.query@x("SELECT * FROM CUSTOMER WHERE C_CUSTKEY>? AND C_CUSTKEY<=?",A5(1),A5(2))
|
7
|
=A5.conj()
|
/合并结果
|
8
|
=interval@s(A1,now())
|
/计算时长
|
测试结果:28秒(非并行用时275秒)并行取数,就要把源数据分成相对平均的多个区间。本例中,C_CUSTKEY是从1开始的自然数,因此可以先求出总记录数(A2),再用平均分成n段(A4)。然后 A5并行计算,每个线程各自连接数据库,再以C_CUSTKEY区间为参数执行SQL。最后合并多线程的取数结果,作为最终结果。 实际情况中,可能需要采取其它办法设置WHERE条件以获得相对平均的区间。多表并行取数有时候是多个SQL取数,也可以利用并行方法来提速。还是使用TPCH生成的数据,数据总量减少为5G,选用其中的5张表来做测试。当采用非并行取数时,可以发现性能不够理想,代码如下:
|
A
|
B
|
1
|
SELECT * FROM SUPPLIER
|
|
2
|
SELECT * FROM PART
|
|
3
|
SELECT * FROM CUSTOMER
|
|
4
|
SELECT * FROM PARTSUPP
|
|
5
|
SELECT * FROM ORDERS
|
|
6
|
=now()
|
/记录时间
|
7
|
=connect("oracle")
|
/连接数据库
|
8
|
=[A1:A5].(A7.query(~))
|
/顺序执行每条SQL
|
9
|
>A7.close()
|
/关闭连接
|
10
|
=interval@ms(A6,now())
|
/计算时长
|
测试结果:360秒改为并行取数后,可以看到性能提升明显,代码如下:
11
|
=now()
|
/记录时间
|
12
|
fork [A1:A5]
|
=connect("oracle")
|
13
|
|
=B12.query@x(A12)
|
14
|
=interval@ms(A11,now())
|
/计算时长
|
测试结果:167秒尽管多表并行无法保证数据均匀分布,但并行计算也能让取数性能得到有效提升。集算器 SPL 是 Java 写的开源软件,提供了 JDBC 接口,很容易集成到 Java 应用中。
本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。