哈喽,大家好,MySQL作为广泛使用的开源关系型数据库管理系统,应该没有Java开发没使用过吧。
关于MySQL,我们大部分时间都在聊,如何提高查询效率,今天我们来聊聊如何提高MySQL的插入效率。
提高插入效率的方式
一般情况下,数据库是运行在专门的服务器上,提高插入效率最明显的当然是提高服务器配置啦。
比如,使用高性能的CPU和SSD磁盘,使用分布式系统架构,将写入压力分散到多个节点。这个方式的成本也是最高的,老板们当然不会使用这种方式了。
我们还可以从其他方面入手:
考虑到实际的应用场景,我们最可能操作的就是使用第3种实现方式,通过批量插入的方式来提高效率。
探索批量插入
常用的批量插入的方式有2种:
在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