精华内容
下载资源
问答
  • 多数据插入
    千次阅读
    2021-01-27 05:10:57

    最近的项目需要导入大量的数据,插入的过程中还需要边查询边插入。插入的数据量在100w左右。一开始觉得100w的数据量不大,于是就插啊插,吃了个饭,回来一看,在插入了50多w条数据后,每秒就只能插10条了。。觉得很奇怪,为啥越插越慢呢? 于是就开始分析插入的时间损耗,想到了如下的解决方案:(mysql使用的INNODB引擎)

    1.分析是否是由主码,外码,索引造成的插入效率降低

    主码:由于主码是每张表必须有的,不能删除。而mysql会对主码自动建立一个索引,这个索引默认是Btree索引,因此每次插入数据要额外的对Btree进行一次插入。这个额外的插入时间复杂度约为log(n)。这个索引无法删除,因此无法优化。但是每次插入的时候,由于主码约束需要检查主码是否出现,这又需要log(n),能否减少这个开销呢?答案是肯定的。我们可以设置主码为自增id AUTO_INCREMENT ,这样数据库里会自动记录当前的自增值,保证不会插入重复的主码,也就避免了主码的重复性检查。

    外码:由于我的项目的插入表中存在外码,因此每次插入时需要在另一张表检测外码存在性。这个约束是与业务逻辑相关的,不能随便删除。并且这个时间开销应当是与另一张表大小成正比的常数,不应当越插入越慢才对。所以排除。

    索引:为了减少Btree插入的时间损耗,我们可以在建表时先不建索引,先将所有的数据插入。之后我们再向表里添加索引。该方法确实也降低了时间的开销。

    经过以上的折腾,再进行测试,发现速度快了一点,但是到了50w条后又开始慢了。看来问题的关键不在这里。于是继续查资料,又发现了个关键问题:

    更多相关内容
  • 使用mybatis plus批量插入数据

    万次阅读 热门讨论 2020-04-15 21:16:24
    之前用mybaits插入数据时,需要在sql语句中作特殊的处理,然后才能够批量插入数据。 今天试验了一下mybatis plus的批量插入方式,简直太简单了,太爽了,真真切切的体会到了科技就是生产力。。 直接上代码,一条语句...

    之前用mybaits插入数据时,需要在sql语句中作特殊的处理,然后才能够批量插入数据。
    今天试验了一下mybatis plus的批量插入方式,简直太简单了,太爽了,真真切切的体会到了科技就是生产力。。

    直接上代码,一条语句就搞定,太爽了!!!

        @Autowired
        private OrderDetailsService orderDetailsService;
        
         // 进行订单细节插入
         List<OrderDetails> orderDetailsList = order.getOrderDetailsList();
         for (OrderDetails orderDetails : orderDetailsList) {
             orderDetails.setOrderid(order.getId());
             orderDetails.setCreatTime(Integer.valueOf(DateUtils.getCurrDateTimeStamp()));
             orderDetails.setUpdTime(Integer.valueOf(DateUtils.getCurrDateTimeStamp()));
         }
         orderDetailsService.insertBatch(orderDetailsList);
    
    展开全文
  • mysql一次性插入多数据

    千次阅读 2021-01-21 17:06:08
    MySQL数据库表中有自增主键ID,当用SQL插入语句中插入语句带有ID列值记录的时候;1、如果指定了该列的值,则新插入的值不能和已有的值重复,而且必须大于其中最大的一个值;2、也可以不指定该列的值,只将其他列的值...

    MySQL数据库表中有自增主键ID,当用SQL插入语句中插入语句带有ID列值记录的时候;

    1、如果指定了该列的值,则新插入的值不能和已有的值重复,而且必须大于其中最大的一个值;

    2、也可以不指定该列的值,只将其他列的值插入,让ID还是按照MySQL自增自己填;

    具体:

    1.创建数据库

    create table if not exists userInfo (

    id int PRIMARY KEY AUTO_INCREMENT,

    name varchar(50) NOT NULL,

    password varchar(50) NOT NULL

    );

    2.插入数据记录

    insert into userInfo values(1,'aaa','1212');

    当数据表中有自增长主键时,当用SQL插入语句中插入语句带有ID列值记录的时候;

    如果指定了该列的值,则新插入的值不能和已有的值重复,而且必须大于其中最大的一个值;

    也可以不指定该列的值,只将其他列的值插入,让ID还是按照MySQL自增自己填;

    这种情况在进行插入的时候,两种解决方法:

    ①可以把id的值设置为null或者0,这样子mysql都会自己做处理

    ②手动指定需要插入的列,不插入这一个字段的数据!

    #方法①:

    insert into userInfo values(null,'ddf','8979');

    insert into userInfo values(0,'ddf','8979');

    #方法②:

    insert into userInfo(name,password) values('ddf','8979');

    3、一次性插入多条数据

    insert into userInfo(name,password) values('ddf','8979'),('fsd','343'),('sf','45');

    展开全文
  • MySQL基础:线程插入数据

    千次阅读 2021-11-26 20:06:03
    向MySQL数据库InnoDB引擎:插入10万条数据。 2 单线程 一个线程插入10万条数据。 package com.monkey.java_study.thread; import com.monkey.java_study.common.config.ThreadPoolConfig; import ...

    1 应用场景

    向MySQL数据库(InnoDB引擎):插入大量数据,如10万条数据,对于离线任务而言,
    可以选择单线程也可以选择多线程,
    本文通过对比单线程和多线程插入数据的速度,建议使用多线程。
    单线程:直接使用MySQL原生客户端或者Workbench客户端直接使用SQL语句执行,或者,使用Java实现;
    多线程:使用Java API实现,进行测试。

    2 测试

    2.1 单线程

    一个线程插入10万条数据。

    package com.monkey.java_study.thread;
    
    import com.monkey.java_study.common.config.ThreadPoolConfig;
    import com.monkey.java_study.database.DatabaseConnectionFactory;
    import com.monkey.java_study.database.IDatabaseConnection;
    import org.apache.logging.log4j.LogManager;
    import org.apache.logging.log4j.Logger;
    
    import java.math.BigDecimal;
    import java.sql.Connection;
    import java.sql.SQLException;
    import java.sql.Statement;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.stream.Collectors;
    import java.util.stream.Stream;
    
    import static com.monkey.java_study.common.constant.DatabaseConstant.MY_SQL;
    
    /**
     * 线程池测试.
     *
     * @author xindaqi
     * @date 2021-11-26 10:40
     */
    public class ThreadPoolTest {
    
        private static final Logger logger = LogManager.getLogger(ThreadPoolTest.class);
    
        private static final Integer NUMBER_OF_THREADS = 5;
        
        /**
         * 单线程插入数据.
         */
        public static void singleThreadInsertDataTest() {
    
            DatabaseConnectionFactory databaseConnectionFactory = new DatabaseConnectionFactory();
            IDatabaseConnection databaseConnection = databaseConnectionFactory.databaseConnection(MY_SQL);
            Connection conn = databaseConnection.databaseLink();
            Statement stmt = null;
            try {
                final Integer ROW_NUMBER_START = 0;
                final Integer ROW_NUMBER_END = 100000;
                Connection connUse = conn;
                stmt = connUse.createStatement();
                String emb = "'test_data'";
                long start = System.currentTimeMillis();
                for (int i = ROW_NUMBER_START; i < ROW_NUMBER_END; i++) {
                    String sql = String.format("INSERT INTO `db_monkey_run`.`tb_test_insert` (emb) VALUES (%s)", emb);
                    int flag = stmt.executeUpdate(sql);
                }
                long end = System.currentTimeMillis();
                long timeCost = end - start;
    
                BigDecimal timeCostBd = new BigDecimal(timeCost);
                long ONE_MINUTE_UNIT = 60000L;
                BigDecimal unitBd = new BigDecimal(ONE_MINUTE_UNIT);
                double timeCostMin = timeCostBd.divide(unitBd, 3, BigDecimal.ROUND_HALF_UP).doubleValue();
                logger.info(">>>>>>>>>Single thread insert database, data number:{}, time cost:{} min", ROW_NUMBER_END, timeCostMin);
            } catch (SQLException se) {
                throw new RuntimeException(se);
            } catch (Exception e) {
                throw new RuntimeException(e);
            } finally {
                try {
                    if (stmt != null) {
                        stmt.close();
                    }
                    if (conn != null) {
                        conn.close();
                    }
                } catch (SQLException se1) {
                    throw new RuntimeException(se1);
                }
            }
        }
    
        public static void main(String[] args) {
            try {
                singleThreadInsertDataTest();
            } catch (Exception ex) {
                throw new RuntimeException(ex);
            } finally {
                ThreadPoolConfig.threadPoolExecutorGenerate.shutdown();
            }
        }
    }
    

    测试结果如图2.1所示。由测试结果可是,单线程插入10万条数据耗时2.653分钟。
    在这里插入图片描述

    图2.1 单线程插入数据

    2.2 多线程

    多线程从线程池中获取线程,线程池配置如下。

    2.2.1 线程池

    package com.monkey.java_study.common.config;
    
    import com.monkey.java_study.common.constant.ThreadPoolConstant;
    
    import java.util.concurrent.*;
    
    /**
     * 线程池配置.
     *
     * @author xindaqi
     * @date 2021-11-24 15:31
     */
    public class ThreadPoolConfig {
    
        /**
         * 线程池
         */
        public static ExecutorService threadPoolExecutorGenerate = new ThreadPoolExecutor(
                ThreadPoolConstant.CORE_THREAD_NUM,
                ThreadPoolConstant.MAX_THREAD_NUM,
                ThreadPoolConstant.KEEP_ALIVE_TIME_SECONDS,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<Runnable>(ThreadPoolConstant.QUEUE_LENGTH),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy());
    }
    

    线程池常量

    package com.monkey.java_study.common.constant;
    
    /**
     * 线程池常量.
     *
     * @author xindaqi
     * @date 2021-07-22 16:48
     */
    public class ThreadPoolConstant {
    
        /**
         * 核心线程数量
         */
        public static final int CORE_THREAD_NUM = 10;
    
        /**
         * 最大线程数量
         */
        public static final int MAX_THREAD_NUM = 15;
    
        /**
         * 非核心线程存活时间
         */
        public static final long KEEP_ALIVE_TIME_SECONDS = 1L;
    
        /**
         * 任务队列长度
         */
        public static final int QUEUE_LENGTH = 8;
    
        /**
         * 线程超时时间
         */
        public static final long TIME_OUT = 70;
    
        private ThreadPoolConstant() {
            throw new AssertionError(ThreadPoolConstant.class.getName() + StringConstant.PRIVATE_INSTANCE_ERROR);
        }
    }
    

    2.2.2 多线程写入

    五个线程,每个线程插入2万条数据。

    package com.monkey.java_study.thread;
    
    import com.monkey.java_study.common.config.ThreadPoolConfig;
    import com.monkey.java_study.database.DatabaseConnectionFactory;
    import com.monkey.java_study.database.IDatabaseConnection;
    import org.apache.logging.log4j.LogManager;
    import org.apache.logging.log4j.Logger;
    
    import java.math.BigDecimal;
    import java.sql.Connection;
    import java.sql.SQLException;
    import java.sql.Statement;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.stream.Collectors;
    import java.util.stream.Stream;
    
    import static com.monkey.java_study.common.constant.DatabaseConstant.MY_SQL;
    
    /**
     * 线程池测试.
     *
     * @author xindaqi
     * @date 2021-11-26 10:40
     */
    public class ThreadPoolTest {
    
        private static final Logger logger = LogManager.getLogger(ThreadPoolTest.class);
    
        private static final Integer NUMBER_OF_THREADS = 5;
    
        /**
         * 多线程插入数据.
         *
         * @param threadNumber 线程号
         * @param batch        数据量
         */
        public static void multipleThreadInsertDataTest(int threadNumber, int batch) {
    
            DatabaseConnectionFactory databaseConnectionFactory = new DatabaseConnectionFactory();
            IDatabaseConnection databaseConnection = databaseConnectionFactory.databaseConnection(MY_SQL);
            Connection conn = databaseConnection.databaseLink();
            Statement stmt = null;
            try {
                final Integer ROW_NUMBER_START = threadNumber * batch;
                final Integer ROW_NUMBER_END = threadNumber * batch + batch;
                Connection connUse = conn;
                stmt = connUse.createStatement();
                String emb = "'test_data'";
                long start = System.currentTimeMillis();
                for (int i = ROW_NUMBER_START; i < ROW_NUMBER_END; i++) {
                    String sql = String.format("INSERT INTO `db_monkey_run`.`tb_test_insert` (emb) VALUES (%s)", emb);
                    int flag = stmt.executeUpdate(sql);
                }
                long end = System.currentTimeMillis();
                long timeCost = end - start;
                BigDecimal timeCostBd = new BigDecimal(timeCost);
                long ONE_MINUTE_UNIT = 60000L;
                BigDecimal unitBd = new BigDecimal(ONE_MINUTE_UNIT);
                double timeCostMin = timeCostBd.divide(unitBd, 3, BigDecimal.ROUND_HALF_UP).doubleValue();
                logger.info(">>>>>>>>>Multiple thread insert database, data number:{}, time cost:{} min", ROW_NUMBER_END, timeCostMin);
            } catch (SQLException se) {
                throw new RuntimeException(se);
            } catch (Exception e) {
                throw new RuntimeException(e);
            } finally {
                try {
                    if (stmt != null) {
                        stmt.close();
                    }
                    if (conn != null) {
                        conn.close();
                    }
                } catch (SQLException se1) {
                    throw new RuntimeException(se1);
                }
            }
        }
    
        public static void main(String[] args) {
            try {
                // 批量数据:2万条
                int insertBatch = 20000;
                // 5个线程:每个线程插入20万条数据
                for (int i = 0; i < NUMBER_OF_THREADS; i++) {
                    final int thread = i;
                    ThreadPoolConfig.threadPoolExecutorGenerate.submit(() -> multipleThreadInsertDataTest(thread, insertBatch));
                }
    
            } catch (Exception ex) {
                throw new RuntimeException(ex);
            } finally {
                ThreadPoolConfig.threadPoolExecutorGenerate.shutdown();
            }
        }
    }
    

    测试结果如图2.2所示。由测试结果可是,单线程插入10万条数据耗时2.653分钟。
    在这里插入图片描述

    图2.2 多线程插入数据

    3 小结

    序号线程时间
    1单线程2.635分钟/线程
    2多线程0.861分钟/线程
    • 多线程处理数据比单线程处理速度快;
    • 对于批量插入数据任务,将数据拆分成批量数据,多线程执行;
    展开全文
  • springBoot实现线程数据插入数据库

    千次阅读 2020-11-06 17:51:13
    网上很博友都实现了springboot项目的大量数据异步执行插入数据库,这样可以实现先返回给页面执行完成的结果,其实线程还没有执行完成,现在下面着重介绍一下使用线程实时导入数据库(阻塞式线程)。...
  • 开发目的:提高百万级数据插入效率。 采取方案:利用ThreadPoolTaskExecutor线程批量插入。 采用技术:springboot2.1.1+mybatisPlus3.0.6+swagger2.5.0+Lombok1.18.4+postgresql+ThreadPoolTaskExecutor等。 ...
  • MySql 插入数据

    千次阅读 2022-05-20 01:11:52
    插入数据
  • 但是这种方式一次只能插入一条数据,要想同时插入多数据,就需要多次调用此SQL语句,这就意味着需要多次与数据库建立连接。这样一来,就会增加服务器的负荷,因为,执行每一次SQL服务器都要同样对SQL进行分析、...
  • Hive/Impala批量插入数据

    千次阅读 2020-12-30 20:19:21
    问题描述现有几千条数据,需要插入到对应的Hive/Impala表中。...比在MySQL中批量插入数据了,因而抱怨Impala不太好用问题分析首先,必须明确的是,把每条数据处理成insert语句的方式,肯定是最低效的,不管是在...
  • Oracle插入数据

    千次阅读 2021-04-30 08:32:37
    在本教程中将学习如何使用Oracle INSERT语句将数据插入到表中。Oracle INSERT语句简介要将新行插入到表中,请按如下方式使用Oracle INSERT语句:INSERT INTO table_name (column_1, column_2, column_3, ... column_...
  • 通过改成一次插入多数据,id通过触发器自动设置,不再每次先查询sequence,这样效率可以提高很多。 由于insert all方式插入多数据时,通过sequence获取的值是同一个,不会自动获取多个,所以id需要通过其他方式...
  • oracle插入多数据

    千次阅读 2018-11-05 21:13:40
    插入多数据: insert all into shopinfo values('A','甲',2) into shopinfo values('B','乙',4) into shopinfo values('C','丙',1) into shopinfo values('A','丁',2) into shopinfo values('B','丙',5) ...
  • Hive_Hive 数据插入

    千次阅读 2020-04-08 23:19:47
    Hive支持插入,可以在同一个查询中使用个insert子句,这样的好处是我们只需要扫描一遍源表就可以生成个不相交的输出! 例子 : from test1 insert overwrite table test2 partition (ag...
  • 首先创建一个表,这个数据表有三个字段 表名 TabName_Lbwsh Create Table TabName_Lbwsh( id varchar(36) not null, Code varchar(36) not null, Name varchar(36) not null ) 查询这个数据表,此时数据表还未有...
  • SQL插入数据

    千次阅读 2021-11-30 23:39:20
    SQL-插入数据;在日常工作中,我们经常会对已经建好的表进行插入数据操作,或者复制整张表的数据,当执行这些操作时我们将用到以下语句
  • 数据库基础之插入数据

    千次阅读 2022-05-01 08:43:03
    如何利用SQL的INSERT语句将数据插入表中。 1、数据插入 INSERT用来将行插入(或添加)到数据库表。插入有几种方式: 插入完整的行; 插入行的一部分; 插入某些查询的结果。 提示:插入及系统安全 使用INSERT...
  • 我们先来创建一种表Authors: CREATE TABLE Authors( AuthID SMALLINT NOT NULL PRIMARY KEY, AuthFN VARCHAR(20), AuthMN VARCHAR(20), AuthLN VARCHAR...然后向表中一次性插入多数据,sql插入代码如下: INSER...
  • mybatis使用线程批量插入数据

    千次阅读 2020-04-08 22:38:27
    昨天在项目中有一个excel导表的操作,于是就想着用线程插入数据。网上找了下mabayis线程插入数据,看了很都是配置的xml,但我不是很喜欢写xml.....于是自己手写了一个,代码可能不是很优雅,但还是记录一下.不...
  • 一、springboot 如果你使用的是springboot那很简单,只需在方法的头部添加@Transactional(rollbackFor = Exception.class)即可 例如 在我的Service @service class UserServiceImpl{ @Transactional(rollback...
  • Oracle一次插入多数据

    万次阅读 2020-01-17 16:16:07
    Oracle一次插入多数据 oracle不像mysql那样可以在values后面添加多个插入的值,mysql具体操作 mysql插入多数据 -- mysql插入多行代码 insert into CB_PRACTICE(id_, type_,remark) values (5,'物理','浮力'),(6,...
  • mybatis insert 插入多数据

    千次阅读 2020-10-23 16:55:46
    MySql/ORacle 批量新增插入
  • 数据插入到MySQL表中的详细教程

    千次阅读 2021-01-18 18:31:01
    数据插入到MySQL表,需要使用SQL INSERT INTO命令。可以将数据插入到MySQL表使用mysql>提示符下或使用任何脚本,如PHP。语法:下面是通用的SQL语法INSERT INTO命令来插入数据到MySQL表:INSERT INTO table_name ...
  • MyBatis批量插入大量数据

    千次阅读 多人点赞 2022-04-17 11:00:18
    用一个 for 循环,把数据一条一条的插入(这种需要开启批处理)。 生成一条插入 sql,类似这种 insert into user(username,address) values(‘aa’,‘bb’),(‘cc’,‘dd’)…。 到底哪种快呢? 我们从两方面来考虑...
  • 关于insert语句,相信大多数程序开发人员都比较熟悉,在平时开发过程中用的最多的可能就是单表单条插入、单表插入的用法,使用插入的用法则用的比较少,今天我们就一起看下: 第一种:单表单条插入 ...
  • Oracle批量插入数据的三种方式

    千次阅读 2021-05-05 03:08:23
    第一种:begininsert into tableName(column1, column2, column3...) values(value1,value2,value3...);insert into tableName(column1, column2, column3...) values(value1,value2,value3...);...
  • hive学习之数据插入操作

    千次阅读 2021-05-18 20:31:27
    1、插入于法 insert into 和insert overwrite INSERT INTO TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...)] select_statement1 FROM from_statement; INSERT OVERWRITE TABLE tablename1 ...
  • 文章目录一、前言二、批量插入前准备1、插入数据表的字段2、计算一行字段占用的空间3、在数据里做插入操作的时候,整体时间的分配三、批量插入数据测试1、SQL语句的大小限制2、查看服务器上的参数:3、计算一次能...
  • 如何用insert into values插入多数据

    万次阅读 2019-05-07 16:25:25
    insert into 表名(字段名1,字段名2)values(值a1,值b1), (值a2,值b2), 例如: insert into user_info (user_account,user_name,user_age,user_class) values (‘00001’, '张三 ',‘20’,‘计算机系’), (‘00002...
  • Mybatis如何批量插入数据

    千次阅读 2022-07-01 15:03:57
        有一小段时间没有写技术博文了,今天我又来更新啦5月份中间...    数据的单条插入,小伙伴应该对此并不陌生了,因为在之前的博文中已经介绍过如何进行基础的增加数据过程,这里不再累赘,如果这部分......

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,394,122
精华内容 957,648
关键字:

多数据插入

友情链接: dccsease_magic.rar