欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

MySQLJDBCStatement.executeBatch實(shí)踐問(wèn)題是怎樣的

這篇文章將為大家詳細(xì)講解有關(guān)MySQL JDBC Statement.executeBatch實(shí)踐問(wèn)題是怎樣的,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對(duì)相關(guān)知識(shí)有一定的了解。

創(chuàng)新互聯(lián)建站是一家專(zhuān)注于成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作與策劃設(shè)計(jì),阜南網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)建站做網(wǎng)站,專(zhuān)注于網(wǎng)站建設(shè)10余年,網(wǎng)設(shè)計(jì)領(lǐng)域的專(zhuān)業(yè)建站公司;建站業(yè)務(wù)涵蓋:阜南等地區(qū)。阜南做網(wǎng)站價(jià)格咨詢(xún):028-86922220

MySQL JDBC Statement.executeBatch實(shí)踐(執(zhí)行效率低)

現(xiàn)在很少使用原生jdbc去實(shí)現(xiàn)代碼, 最近在測(cè)試MySQL批處理數(shù)據(jù)遇到一個(gè)問(wèn)題: 執(zhí)行Statement.executeBatch時(shí)效率極其低下(插入10000條數(shù)據(jù)), 斷點(diǎn)調(diào)試時(shí)在此處停頓很長(zhǎng)時(shí)間(908712ms)

數(shù)據(jù)版本:

select version();
// 5.7.17-11-V2.0R530D002-20190816-1203-log

數(shù)據(jù)庫(kù)表:

CREATE TABLE `t_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_name` varchar(64) DEFAULT NULL,
  `age` smallint(6) DEFAULT NULL,
  `salary` decimal(10,2) DEFAULT NULL,
  `max_size` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;

測(cè)試代碼如下:

public class BatchTest {
    public static void main(String[] args) throws SQLException, ClassNotFoundException {
        batch("com.mysql.cj.jdbc.Driver",
                "jdbc:mysql://localhost:3306/test?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useUnicode=true&useSSL=false&allowMultiQueries=true",
                "root", "123456");
    }

    private static void batch(String driver, String url, String username, String password) throws ClassNotFoundException, SQLException {
        // jdbc driver: mysql-connector-java:8.0.21
        Class.forName(driver);
        Connection conn = DriverManager.getConnection(url, username, password);
        conn.setAutoCommit(false);
         PreparedStatement pstmt = conn.prepareStatement("select * from dual");
        for(int i = 1; i <= 10000; i++){
            String batchSql = "insert into t_user(user_name, age, salary, max_size) values (" +
                    "'name" + i + "'," + i + "," + i + "," + i +
                    ")";
            pstmt.addBatch(batchSql);
        }
        long start = System.currentTimeMillis();
        // 執(zhí)行耗時(shí)很長(zhǎng)
        int[] rs = pstmt.executeBatch();
        conn.commit();
        // total ======> 908712
        System.out.println("total ======> " + (System.currentTimeMillis() - start));

    }
}

原因

  1. addBatch() 是在PreparedStatement定義的, addBatch(String) 是在Statement定義的,

  2. MySQL JDBC驅(qū)動(dòng)在默認(rèn)情況下使用預(yù)編譯會(huì)無(wú)視executeBatch()語(yǔ)句, 把我們期望批量執(zhí)行的一組sql語(yǔ)句拆散, 一條一條地發(fā)給MySQL數(shù)據(jù)庫(kù), 直接造成較低的性能.

  3. batchHasPlainStatements=true, 即使用PreparedStatement時(shí)使用了Statement.addBatch(String), 不執(zhí)行批處理操作, 一條一條地發(fā)給MySQL數(shù)據(jù)庫(kù), 直接造成較低的性能.(確使用方式: PreparedStatement + addBatch(), Statement + addBatch(sql))

JDBC驅(qū)動(dòng)源碼:

public class ClientPreparedStatement extends com.mysql.cj.jdbc.StatementImpl implements JdbcPreparedStatement {
    /**
     * Does the batch (if any) contain "plain" statements added by
     * Statement.addBatch(String)?
     * 
     * If so, we can't re-write it to use multi-value or multi-queries.
     */
    protected boolean batchHasPlainStatements = false;
    // ......
    protected long[] executeBatchInternal() throws SQLException {
            synchronized (checkClosed().getConnectionMutex()) {
    
                if (this.connection.isReadOnly()) {
                    throw new SQLException(Messages.getString("PreparedStatement.25") + Messages.getString("PreparedStatement.26"),
                            MysqlErrorNumbers.SQL_STATE_ILLEGAL_ARGUMENT);
                }
    
                if (this.query.getBatchedArgs() == null || this.query.getBatchedArgs().size() == 0) {
                    return new long[0];
                }
    
                // we timeout the entire batch, not individual statements
                int batchTimeout = getTimeoutInMillis();
                setTimeoutInMillis(0);
    
                resetCancelledState();
    
                try {
                    statementBegins();
    
                    clearWarnings();
                     // 1. batchHasPlainStatements 包含原始sql語(yǔ)句
                     // 2. rewriteBatchedStatements 使用批量
                    if (!this.batchHasPlainStatements && this.rewriteBatchedStatements.getValue()) {
    
                        if (((PreparedQuery<?>) this.query).getParseInfo().canRewriteAsMultiValueInsertAtSqlLevel()) {
                            return executeBatchedInserts(batchTimeout);
                        }
    
                        if (!this.batchHasPlainStatements && this.query.getBatchedArgs() != null
                                && this.query.getBatchedArgs().size() > 3 /* cost of option setting rt-wise */) {
                            return executePreparedBatchAsMultiStatement(batchTimeout);
                        }
                    }
    
                    return executeBatchSerially(batchTimeout);
                } finally {
                    this.query.getStatementExecuting().set(false);
    
                    clearBatch();
                }
            }
    }
    // ......
}

修正:

  1. 在連接url加上&rewriteBatchedStatements=true, 如: jdbc:mysql://localhost:3306/test?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useUnicode=true&useSSL=false&allowMultiQueries=true&rewriteBatchedStatements=true

  2. 使用Statement.addBatch()替換Statement.addBatch(String)

public class BatchTest {
    public static void main(String[] args) throws SQLException, ClassNotFoundException {
        batch("com.mysql.cj.jdbc.Driver",
                "jdbc:mysql://localhost:3306/test?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useUnicode=true&useSSL=false&allowMultiQueries=true&rewriteBatchedStatements=true",
                "root", "123456");
    }

    private static void batch(String driver, String url, String username, String password) throws ClassNotFoundException, SQLException {
        Class.forName(driver);
        Connection conn = DriverManager.getConnection(url, username, password);
        conn.setAutoCommit(false);
        String pSql = "insert into t_user(user_name, age, salary, max_size) values (?, ?, ?, ?)";
        PreparedStatement pstmt =conn.prepareStatement(pSql);
        for(int i = 1; i <= 10000; i++){
            try {
                pstmt.setString(1, "name" + i);
                pstmt.setInt(2, i);
                pstmt.setInt(3, i);
                pstmt.setInt(4, i);
                pstmt.addBatch();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        long start = System.currentTimeMillis();
        int[] rs = pstmt.executeBatch();
        conn.commit();
        // total ======> 2598
        System.out.println("total ======> " + (System.currentTimeMillis() - start));
    }
}

關(guān)于MySQL JDBC Statement.executeBatch實(shí)踐問(wèn)題是怎樣的就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到。

文章名稱(chēng):MySQLJDBCStatement.executeBatch實(shí)踐問(wèn)題是怎樣的
URL分享:http://chinadenli.net/article28/iegcjp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供用戶體驗(yàn)響應(yīng)式網(wǎng)站、面包屑導(dǎo)航、Google關(guān)鍵詞優(yōu)化、虛擬主機(jī)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

小程序開(kāi)發(fā)
精品少妇人妻av免费看| 欧美性高清一区二区三区视频| 一区二区免费视频中文乱码国产| 亚洲av秘片一区二区三区| 精品欧美日韩一二三区| 精品国产品国语在线不卡| 久久天堂夜夜一本婷婷| 中文字幕一区二区久久综合| 精品al亚洲麻豆一区| 老富婆找帅哥按摩抠逼视频| 亚洲妇女黄色三级视频| 加勒比日本欧美在线观看| 日本精品免费在线观看| 亚洲精品伦理熟女国产一区二区| 欧美日韩精品一区免费| 男女午夜在线免费观看视频| 美女露小粉嫩91精品久久久| 亚洲一区二区三区三州| 精产国品一二三区麻豆| 欧美日韩国产精品黄片| 日本男人女人干逼视频| 亚洲一区二区三区三区| 欧美精品日韩精品一区| 欧美熟妇一区二区在线| 中文字幕人妻日本一区二区| 精品少妇一区二区视频| 日本理论片午夜在线观看| 五月激情婷婷丁香六月网| 亚洲欧美中文日韩综合| 久久国产亚洲精品赲碰热| 欧美大胆女人的大胆人体| 十八禁日本一区二区三区| 丁香六月婷婷基地伊人| 免费观看日韩一级黄色大片| 国产三级视频不卡在线观看| 色婷婷在线精品国自产拍| 黄色在线免费高清观看| 激情内射亚洲一区二区三区| 日韩欧美一区二区不卡视频| 欧美午夜色视频国产精品| 亚洲精品熟女国产多毛|