自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

MySQL怎么快速插入1億條數(shù)據(jù)

數(shù)據(jù)庫 MySQL
提高MySQL插入效率主要可通過調(diào)整數(shù)據(jù)庫配置、選擇適合的存儲引擎以及運用批量插入策略等方式實現(xiàn)。在實際應用中,尤其是在使用ORM框架進行數(shù)據(jù)操作時,應合理選擇并充分利用批量插入功能,以最大程度提升插入效率。

哈嘍,大家好,MySQL作為廣泛使用的開源關系型數(shù)據(jù)庫管理系統(tǒng),應該沒有Java開發(fā)沒使用過吧。

關于MySQL,我們大部分時間都在聊,如何提高查詢效率,今天我們來聊聊如何提高MySQL的插入效率。

提高插入效率的方式

一般情況下,數(shù)據(jù)庫是運行在專門的服務器上,提高插入效率最明顯的當然是提高服務器配置啦。 

比如,使用高性能的CPU和SSD磁盤,使用分布式系統(tǒng)架構,將寫入壓力分散到多個節(jié)點。這個方式的成本也是最高的,老板們當然不會使用這種方式了。

我們還可以從其他方面入手:

  1. 調(diào)整數(shù)據(jù)庫配置:優(yōu)化緩沖池大小、增大批量插入緩沖區(qū)等,通過調(diào)整MySQL數(shù)據(jù)庫參數(shù)的方式。
  2. 選擇使用MyISAM存儲引擎,因為其簡單的表鎖機制和無事務開銷而在插入速度上表現(xiàn)更優(yōu)。
  3. 使用批量插入的方式。

考慮到實際的應用場景,我們最可能操作的就是使用第3種實現(xiàn)方式,通過批量插入的方式來提高效率。

探索批量插入

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

  1. 拼接SQL,使用 insert into xxx (...) values (...),(...),(...)
  2. 利用事務,將批量插入操作封裝在單個事務中,可以減少事務開銷并提高并發(fā)性能。

在mybatisPlus,以及mybatis-flex中,saveBatch 就是使用的這種方式

接下來我們來測試一下這幾個方法。

測試代碼

測試的SQL

CREATE TABLE `orders`  
(  
    `order_id`         BIGINT         NOT NULL AUTO_INCREMENT COMMENT '訂單ID(主鍵)',  
    `customer_id`      BIGINT         NOT NULL COMMENT '客戶ID(關聯(lián)customer表)',  
    `order_status`     tinyint(4)     NOT NULL DEFAULT 1 COMMENT '訂單狀態(tài) 1-待支付 2-已支付 3-待發(fā)貨 4-已發(fā)貨 5-已完成 6-已取消',  
    `payment_method`   tinyint(4)     NULL     DEFAULT null COMMENT '支付方式; 1-現(xiàn)金 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 '優(yōu)惠券減免金額',  
    `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  
<foreach collection="orders" item="item" separator=",">  
    (#{item.orderId}, #{item.customerId}, #{item.orderStatus}, #{item.paymentMethod}, #{item.orderDate}, #{item.totalAmount}, #{item.shippingFee}, #{item.couponDiscount})  
</foreach>

二、使用mybatis-flex提供的saveBatch

ordersService.saveBatch(list);

三、手動控制事務的提交,saveBatchSession

public void saveBatchSession(List<Orders> 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<Orders> list = new ArrayList<>();  
 long s = System.currentTimeMillis();  
 for (long i = start + 1; i <= end; i++) {  
  if ((i - start) % 1000 == 0) {  
   ordersService.saveBatchSession(list);  
//          ordersService.saveBatchXml(list);   
//   ordersService.saveBatch(list);  
   list.clear();  
   itemAll.clear();  
   System.out.println("生成數(shù)據(jù):" + (i - start) + "條,耗時:" + (System.currentTimeMillis() - s) + "ms");  
   s = System.currentTimeMillis();  
   continue;  
  }  
  // 構建所有屬性  
  list.add(Orders.builder() ... .build());
 }  
 ordersService.saveBatch(list);  
}

測試結果

使用了3種方式進行測試

未開啟批處理,batchXml

圖片圖片

未開啟批處理,mybatis-flex提供的saveBatch

圖片圖片

未開啟批處理,saveBatchSession

圖片圖片

從這里的結果可以看出,使用 batchXml 的效率是最高的,遠遠超越其他方式。但是仔細一想,這些數(shù)據(jù)應該很不正常,插入1000條數(shù)據(jù),竟然需要4秒左右,和單條插入1000次的時間幾乎沒有區(qū)別。

開啟批處理

經(jīng)過一番查詢資料,并檢查配置,發(fā)現(xiàn)果然另有玄機,連接數(shù)據(jù)庫的時候沒有開啟批處理

開啟方式:在spring的配置文件中,連接數(shù)據(jù)源時,url需要增加 allowPublicKeyRetrieval=true

然后重新測試一遍。

開啟批處理,saveBatchXml

圖片圖片

開啟批處理,mybatis-flex提供的saveBatch

圖片圖片

開啟批處理,saveBatchSession

圖片圖片

這次的結果就比較正常了,可以看出來:

  • saveBatchSession最快
  • mybatis-flex提供的saveBatch 因為有些額外的操作,多消耗了10ms左右的時間
  • saveBatchXml 相較于另外兩種方式,慢了30ms~40ms。

接下來,把每批次的處理數(shù)據(jù)由1000次增加到10000次,再次進行測試。

開啟批處理,saveBatchXml,10000條一批次

圖片圖片

開啟批處理,saveBatchSession,10000條一批次

圖片圖片

開啟批處理,mybatis-flex提供的saveBatch,10000條一批次

圖片圖片

由此結果可以看出來:

  • saveBatchSession和mybatis-flex提供的saveBatch 耗時基本一致
  • saveBatchXml就明顯的慢一些,按照效率差算,差了將近50%的效率

總結

綜上,提高MySQL插入效率主要可通過調(diào)整數(shù)據(jù)庫配置、選擇適合的存儲引擎以及運用批量插入策略等方式實現(xiàn)。在實際應用中,尤其是在使用ORM框架進行數(shù)據(jù)操作時,應合理選擇并充分利用批量插入功能,以最大程度提升插入效率。

責任編輯:武曉燕 來源: Java技術指北
相關推薦

2024-07-04 13:42:12

2022-04-06 14:15:10

Python數(shù)據(jù)

2018-06-21 09:12:01

編程語言Python數(shù)據(jù)分析

2020-04-24 21:41:45

MySQL數(shù)據(jù)庫插入數(shù)據(jù)

2021-11-02 14:46:50

數(shù)據(jù)

2021-06-16 14:59:59

網(wǎng)絡安全數(shù)據(jù)泄露黑客

2022-09-23 09:44:17

MyBatisforeach

2015-03-03 09:52:02

2023-06-18 23:13:27

MySQL服務器客戶端

2024-03-21 15:39:00

2020-11-05 09:10:11

MYSQL數(shù)據(jù)數(shù)據(jù)庫

2021-09-07 10:55:36

SQLitePythonRust

2022-08-25 18:23:07

攜程HBase存儲Metrics

2011-08-16 09:21:30

MySQL大數(shù)據(jù)量快速語句優(yōu)化

2019-06-24 11:07:34

數(shù)據(jù)數(shù)據(jù)庫存儲

2021-06-29 08:12:22

MySQL數(shù)據(jù)分頁數(shù)據(jù)庫

2021-07-19 15:33:27

編程Rust開發(fā)

2024-09-09 08:15:20

2022-03-28 09:00:48

URLinput過濾器

2023-09-27 22:59:35

MySQLPostgreSQL
點贊
收藏

51CTO技術棧公眾號