达梦数据库通过JDBC批量获取clob数据较慢的问题

示例

--创建测试表
SQL> create table test(id int, info clob);
操作已执行
--插入2万条,clob字段长度为2000的数据,并提交
SQL> insert into test select level,rpad('1',2000,'abcd') from dual connect by level< =20000;
影响行数 20000
SQL> commit;
操作已执行
--查clob字段数据长度
SQL> select lengthb(info) from test limit 1;
行号     lengthb(info)
---------- -------------
1          2000

批量获取clob数据java程序代码:

package jdbc_conn;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

public class test {
	public static void main(String[] args) {
		Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        try {
            //加载数据库驱动
            Class.forName("dm.jdbc.driver.DmDriver");
            connection =  DriverManager.getConnection("jdbc:dm://IP:端口", "用户名", "密码");
            String sql = "select * from test where rownum <=10000";
            preparedStatement = connection.prepareStatement(sql);
            resultSet =  preparedStatement.executeQuery();
            List<String> data = new ArrayList<>();
            Long stime = System.currentTimeMillis();
            while(resultSet.next()){
                data.add(resultSet.getString("info"));
            }
            System.out.println("耗时:"+(System.currentTimeMillis()-stime)+" ms");
        } catch (Exception e) {
            e.printStackTrace();
        }
	}
}

执行java程序获取1万条数据,耗时约10秒
在这里插入图片描述
为什么这么慢?
原因:lob数据根据长度分行内数据和行外数据,行内数据和行外数据在读取逻辑上有差异,会采用不同方式读取,在性能上有较大差别。

解决方法:
dm.ini中有个参数可以更改行内外数据界定。
LOB_MAX_INROW_LEN 动态参数,系统级
指定数据库 LOB 字段的行内数据存放的上限大小,单位为 BYTE,有效值范围(900~8000)。

我们查询一下当前 LOB_MAX_INROW_LEN 的值:

SQL> select para_name,para_value from v$dm_ini where para_name = 'LOB_MAX_INROW_LEN';

行号     para_name         para_value
---------- ----------------- ----------
1          LOB_MAX_INROW_LEN 900

当前为默认值900,但clob数据长度为2000,所以读取方式为行外数据方式读取。

我们将 LOB_MAX_INROW_LEN 参数设置为3000

SQL> sp_set_para_value(1,'LOB_MAX_INROW_LEN',3000);
DMSQL 过程已成功完成
SQL> select para_name,para_value from v$dm_ini where para_name = 'LOB_MAX_INROW_LEN';
行号     para_name         para_value
---------- ----------------- ----------
1          LOB_MAX_INROW_LEN 3000

再次执行java程序,看看有什么变化。
在这里插入图片描述
执行时间为252毫秒,性能有大幅提升,但要注意的是,由于每行数据长度不能超过页大小的一半,所以这个参数设置时需考虑数据库的页大小,否则不起作用。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值