MySQL怎么快速插入1亿条数据

2024年 4月 15日 22.7k 0

哈喽,大家好,MySQL作为广泛使用的开源关系型数据库管理系统,应该没有Java开发没使用过吧。

关于MySQL,我们大部分时间都在聊,如何提高查询效率,今天我们来聊聊如何提高MySQL的插入效率。

提高插入效率的方式

一般情况下,数据库是运行在专门的服务器上,提高插入效率最明显的当然是提高服务器配置啦。 

比如,使用高性能的CPU和SSD磁盘,使用分布式系统架构,将写入压力分散到多个节点。这个方式的成本也是最高的,老板们当然不会使用这种方式了。

我们还可以从其他方面入手:

  • 调整数据库配置:优化缓冲池大小、增大批量插入缓冲区等,通过调整MySQL数据库参数的方式。
  • 选择使用MyISAM存储引擎,因为其简单的表锁机制和无事务开销而在插入速度上表现更优。
  • 使用批量插入的方式。
  • 考虑到实际的应用场景,我们最可能操作的就是使用第3种实现方式,通过批量插入的方式来提高效率。

    探索批量插入

    常用的批量插入的方式有2种:

  • 拼接SQL,使用 insert into xxx (...) values (...),(...),(...)
  • 利用事务,将批量插入操作封装在单个事务中,可以减少事务开销并提高并发性能。
  • 在mybatisPlus,以及mybatis-flex中,saveBatch 就是使用的这种方式

    接下来我们来测试一下这几个方法。

    测试代码

    测试的SQL

    CREATE TABLE `orders`  
    (  
        `order_id`         BIGINT         NOT NULL AUTO_INCREMENT COMMENT '订单ID(主键)',  
        `customer_id`      BIGINT         NOT NULL COMMENT '客户ID(关联customer表)',  
        `order_status`     tinyint(4)     NOT NULL DEFAULT 1 COMMENT '订单状态 1-待支付 2-已支付 3-待发货 4-已发货 5-已完成 6-已取消',  
        `payment_method`   tinyint(4)     NULL     DEFAULT null COMMENT '支付方式; 1-现金 2-支付宝 3-微信 4-银行卡',  
        `total_amount`     DECIMAL(10, 2) NOT NULL COMMENT '订单总金额',  
        `shipping_fee`     DECIMAL(10, 2) NOT NULL DEFAULT 0 COMMENT '运费',  
        `coupon_discount`  DECIMAL(10, 2) NOT NULL DEFAULT 0 COMMENT '优惠券减免金额',  
        `order_date`       DATETIME       NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '下单日期',  
        `payment_time`     DATETIME                DEFAULT NULL COMMENT '支付时间',  
        `shipping_address` VARCHAR(255)   NULL COMMENT '收货地址',  
        `receiver_name`    VARCHAR(50)    NULL COMMENT '收货人姓名',  
        `receiver_phone`   VARCHAR(20)    NULL COMMENT '收货人电话',  
        PRIMARY KEY (`order_id`)  
    ) ENGINE = InnoDB  
      DEFAULT CHARSET = utf8mb4 COMMENT ='订单信息表';

    一、使用 batchXml

    insert into orders (order_id, customer_id, order_status, payment_method, order_date, total_amount, shipping_fee, coupon_discount)  
    values  
      
        (#{item.orderId}, #{item.customerId}, #{item.orderStatus}, #{item.paymentMethod}, #{item.orderDate}, #{item.totalAmount}, #{item.shippingFee}, #{item.couponDiscount})  
    

    二、使用mybatis-flex提供的saveBatch

    ordersService.saveBatch(list);

    三、手动控制事务的提交,saveBatchSession

    public void saveBatchSession(List orders) {  
        SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH);  
        OrdersMapper mapper = session.getMapper(OrdersMapper.class);  
        for (int i = 0,length = orders.size(); i < length; i++) {  
            mapper.insert(orders.get(i));  
        }  
        session.commit();  
        session.clearCache();  
        session.close();  
    }

    启动代码

    @Test
    public void generatorTestData() {
    genOrders(0L, 100000L);
    }

    private void genOrders(long start, long end) {
    List list = new ArrayList();
    long s = System.currentTimeMillis();
    for (long i = start + 1; i

    相关文章

    Oracle如何使用授予和撤销权限的语法和示例
    Awesome Project: 探索 MatrixOrigin 云原生分布式数据库
    下载丨66页PDF,云和恩墨技术通讯(2024年7月刊)
    社区版oceanbase安装
    Oracle 导出CSV工具-sqluldr2
    ETL数据集成丨快速将MySQL数据迁移至Doris数据库

    发布评论