【YashanDB数据库】由于网络带宽不足导致的jdbc向yashandb插入数据慢

问题现象

某客户环境,客户的业务使用jdbc驱动向其他操作系统上的yashandb插入90万条数据,耗时大约30分钟。

问题的风险及影响

影响客户的业务处理效率

问题影响的版本

所有的yashandb版本

问题发生原因

jdbc执行batch insert时,是有绑定变量的。在准备好了PreparedStatement以后,jdbc驱动要向yashandb server发送绑定变量的值。

由于网络带宽不足,这些绑定变量的值发送需要耗费一定时间,最终导致了插入数据效率降低。

解决方法及规避方式

提高jdbc所在操作系统与yashandb server所在操作系统网络之间的带宽

问题分析和处理过程

要插入数据表的ddl如下:

CREATE TABLE "LOCATION_INFO_INDEX000001"
(
"ID" VARCHAR(36) NOT NULL,
"VEHICLENO" VARCHAR(11) NOT NULL,
"VEHICLECOLOR" NUMBER(1,0) NOT NULL,
"MILEAGE" NUMBER(11,0) NOT NULL,
"LONGITUDE" NUMBER(16,6) NOT NULL,
"LATITUDE" NUMBER(16,6) NOT NULL,
"HEIGHT" NUMBER(11,0) NOT NULL,
"SPEED" NUMBER(11,0) NOT NULL,
"DIRECTION" NUMBER(11,0) NOT NULL,
"DATETIME" NUMBER(16,0) NOT NULL,
"DATE" VARCHAR(10) NOT NULL,
"ALARM" NUMBER(11,0) NOT NULL,
"STATE" NUMBER(11,0),
"MSGGNSSCENTERID" VARCHAR(255),
"MSGGNSSCENTERNAME" VARCHAR(255),
"INS" NUMBER,
"SEQ" NUMBER,
"UPDATESTATUS" NUMBER,
"UPDATETIME" VARCHAR2(50),
CONSTRAINT "LOCATION_INFO_INDEX000001_PKEY" PRIMARY KEY("ID")) ;

使用如下的java代码作为jdbc客户端向yashandb server插入数据:

public void test_slow_table(Connection conn){
        try{
            //System.out.println(DBUtil.buildInsertMeta(conn, "SZSJYJTGK", "LOCATION_INFO_INDEX000001"));
            conn.setAutoCommit(false);
            PreparedStatement ps = conn.prepareStatement("insert into LOCATION_INFO_INDEX000001(ID ,VEHICLENO ,VEHICLECOLOR ,MILEAGE ," +
                    "LONGITUDE ,LATITUDE ,HEIGHT ,SPEED ,DIRECTION ,\"DATETIME\" ,\"DATE\" ,ALARM ,\"STATE\" ,MSGGNSSCENTERID ,MSGGNSSCENTERNAME ,INS ,SEQ ,UPDATESTATUS ," +
                    "add_time,UPDATETIME,by01,by02) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
 
            System.out.println("1: " + Instant.now());
            long start = System.currentTimeMillis();
            int base = 100900000;
            for(int i = base;i < base+100000; i++) {
                //ID                                                               NOT NULL  VARCHAR(144)
                //System.out.println("add id_" + i);
                ps.setString(1, "id_" + i);
                //VEHICLENO                                                        NOT NULL  VARCHAR(44)
                ps.setString(2, "abcd");
                //VEHICLECOLOR                                                     NOT NULL  NUMBER(1)
                ps.setInt(3,1);
                //MILEAGE                                                          NOT NULL  NUMBER(11)
                ps.setInt(4, i);
                //LONGITUDE                                                        NOT NULL  NUMBER(16,6)
                ps.setInt(5, i);
                //LATITUDE                                                         NOT NULL  NUMBER(16,6)
                ps.setInt(6,i);
                //HEIGHT                                                           NOT NULL  NUMBER(11)
                ps.setInt(7,i);
                //SPEED                                                            NOT NULL  NUMBER(11)
                ps.setInt(8,i);
                //DIRECTION                                                        NOT NULL  NUMBER(11)
                ps.setInt(9,i);
                //DATETIME                                                         NOT NULL  NUMBER(16)
                ps.setInt(10,i);
                //DATE                                                             NOT NULL  VARCHAR(40)
                ps.setString(11, "abcd");
                //ALARM                                                            NOT NULL  NUMBER(11)
                ps.setInt(12,i);
                //STATE                                                                      NUMBER(11)
                ps.setInt(13,i);
                //MSGGNSSCENTERID                                                            VARCHAR(1020)
                ps.setString(14,StringUtil.buildString(256));
                //MSGGNSSCENTERNAME                                                          VARCHAR(1020)
                ps.setString(15,StringUtil.buildString(256));
                //INS                                                                        NUMBER
                ps.setInt(16,i);
                //SEQ                                                                        NUMBER
                ps.setInt(17,i);
                //UPDATESTATUS                                                               NUMBER
                ps.setInt(18,i);
                //ADD_TIME                                                                   TIMESTAMP
                ps.setTimestamp(19,new Timestamp(System.currentTimeMillis()));
                //UPDATETIME                                                                 TIMESTAMP
                ps.setTimestamp(20,new Timestamp(System.currentTimeMillis()));
                ps.setString(21,StringUtil.buildString(256));
                ps.setString(22,StringUtil.buildString(256));
 
 
                ps.addBatch();
                if((i+1)%1000 == 0){
                    System.out.println("21:" + Instant.now());
                    ps.executeBatch();
                    conn.commit();
                }
            }
            System.out.println("2:" + Instant.now());
            ps.executeBatch();
            System.out.println("3:" + Instant.now());
            conn.commit();
            System.out.println("4:" + Instant.now());
            long end = System.currentTimeMillis();
            System.out.println("cost:" + (end-start) + " ms");
 
        }catch (Exception e){
            e.printStackTrace();
        }
    }

jdbc客户端和yashandb server不在一个操作系统时,其网络带宽大概为800KB/s

插入10万条数据,大概耗时130s:

同样的jdbc代码在运行yashandb的操作系统上执行,耗时4s左右:

可以得出结论,耗时基本都花在了网络传输上。

经验总结

客户端代码在yashandb运行的操作系统上执行,可以去除掉网络传输的影响,方便分析问题

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用 JDBC数据库插入数据需要以下几个步骤: 1. 加载数据库驱动程序 在使用 JDBC 操作数据库之前,需要先加载数据库驱动程序。比如,如果要连接 MySQL 数据库,则需要加载 MySQL 的 JDBC 驱动程序。可以通过以下代码加载 MySQL 驱动程序: ``` Class.forName("com.mysql.jdbc.Driver"); ``` 2. 建立数据库连接 使用 DriverManager 类的 getConnection() 方法建立数据库连接。getConnection() 方法需要传入三个参数:数据库连接 URL、用户名和密码。例如: ``` Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "123456"); ``` 3. 创建 SQL 语句 使用 SQL 语句向数据库插入数据。例如,以下代码创建一个 INSERT 语句: ``` String sql = "INSERT INTO user(name, age, email) VALUES('Tom', 18, 'tom@example.com')"; ``` 4. 执行 SQL 语句 使用 Statement 或 PreparedStatement 对象执行 SQL 语句。例如,以下代码使用 Statement 对象执行 INSERT 语句: ``` Statement stmt = conn.createStatement(); stmt.executeUpdate(sql); ``` 5. 关闭数据库连接 在使用完数据库后,需要关闭数据库连接。例如: ``` stmt.close(); conn.close(); ``` 完整的 Java 代码示例: ``` import java.sql.*; public class JdbcDemo { public static void main(String[] args) { try { // 加载数据库驱动程序 Class.forName("com.mysql.jdbc.Driver"); // 建立数据库连接 Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "123456"); // 创建 SQL 语句 String sql = "INSERT INTO user(name, age, email) VALUES('Tom', 18, 'tom@example.com')"; // 执行 SQL 语句 Statement stmt = conn.createStatement(); stmt.executeUpdate(sql); // 关闭数据库连接 stmt.close(); conn.close(); } catch (Exception e) { e.printStackTrace(); } } } ``` 注意:以上代码示例仅供参考,实际使用时需要根据具体情况修改。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值