使用batch insert解決MySQL的insert吞吐量問題

来源:http://www.cnblogs.com/zhenghongxin/archive/2016/05/05/5461130.html
-Advertisement-
Play Games

最近使用了一個非常簡單易用的方法解決了業務上的一個insert吞吐量的問題,在此總結一下。 首先我們明確一下,insert吞吐量其實並不是指的IPS(insert per second),而是指的RPS(effect rows per second)。 其次我們再說一下batch insert,其實 ...


最近使用了一個非常簡單易用的方法解決了業務上的一個insert吞吐量的問題,在此總結一下。

首先我們明確一下,insert吞吐量其實並不是指的IPS(insert per second),而是指的RPS(effect rows per second)。

其次我們再說一下batch insert,其實顧名思義,就是批量插入。這種優化思想是很基本的,MySQL中最出名的應用就是group commit。

簡單的來說,就是將SQL A 變成 SQL B

SQL A : insert into table values ($values);
SQL B : insert into table values ($values),($values)...($values);

下麵,我們來看看這種異常簡單的改動會帶來什麼樣子的變化。

測試環境交代:單id的表結構,10w個int values,本地使用socket連接MySQL server,使用shell單進程測試。

首先,我們看下使用SQL A將10w個int values插入到test表中所需的耗時,耗時1777秒。

real    29m37.090s
user    9m11.705s
sys     5m0.762s

然後,我們看下使用SQL B(每次insert,插入10 values)將10w個int values插入到test表中所需的耗時,耗時53秒

real    0m53.871s
user    0m19.455s
sys     0m6.285s

這是整整近33倍的時間提升。這部分性能提升的原因在於以下幾點:

1、每次和MySQL server建立連接都需要經過各種初始化、許可權認證,語法解析等等多個步驟,需要消耗一定的資源。

2、更新一個values和更新n個values耗時基本一致。(下麵對比一下insert 單values核insert 10 values的profile耗時)

單values:
+------------------------------+----------+
| Status                       | Duration |
+------------------------------+----------+
| starting                     | 0.000056 |
| checking permissions         | 0.000010 |
| Opening tables               | 0.000034 |
| System lock                  | 0.000010 |
| init                         | 0.000011 |
| update                       | 0.000061 |
| Waiting for query cache lock | 0.000003 |
| update                       | 0.000015 |
| end                          | 0.000003 |
| query end                    | 0.000053 |
| closing tables               | 0.000009 |
| freeing items                | 0.000021 |
| logging slow query           | 0.000002 |
| cleaning up                  | 0.000003 |
+------------------------------+----------+

10 values:
+------------------------------+----------+
| Status                       | Duration |
+------------------------------+----------+
| starting                     | 0.000061 |
| checking permissions         | 0.000008 |
| Opening tables               | 0.000027 |
| System lock                  | 0.000008 |
| init                         | 0.000012 |
| update                       | 0.000073 |
| Waiting for query cache lock | 0.000003 |
| update                       | 0.000010 |
| end                          | 0.000008 |
| query end                    | 0.000053 |
| closing tables               | 0.000010 |
| freeing items                | 0.000021 |
| logging slow query           | 0.000002 |
| cleaning up                  | 0.000003 |
+------------------------------+----------+

但是,是否values積攢的越多,效率越高嗎? 答案自然是否定的,任何優化方案都不會是純線性的,肯定會在某個條件下出現拐點。

我們按照不同的values number進行測試,分別為1、10、50、100、200、500、1000、5000、10000.

從下圖我們可以看出,隨著values number的增加,耗時先是急劇下降,從1777s變成53s,然後在增加values number就不會有太大的變化,直到values number超過200,最後的10000個values number耗時達到了2分鐘。

從下圖我們可以看到隨著values numbers的增加,QPS(藍線)先是猛增,然後下降,最終小於1/s。而RPS(綠線)隨著增加猛增到一個高level,然後隨著增加逐步下降,超過5000個values number之後開始急劇下降。

另,最關鍵的是, QPS最高峰和RPS的最高峰並不在同一個values number下,也就是說QPS最高的時候並不代表著insert的吞吐量就最高 。

在我這個簡單測試場景中,values number最合適的值是50,和單values對比,耗時減少 97% ,insert吞吐量提升 36倍 

而這個值和表結構和欄位類型及大小都有關係。需要根據不同的場景進行測試之後才可以得出,但是普遍來說,50-100是比較推薦的考慮值。

至於這個如何實現,只要前端寫入的時候加入隊列即可,可以按照2個條件進行合併

  • 隊列中積攢到n個values number後在寫入資料庫,優點是性能最高,缺點是時間不可控,有可能等到第n個需要n秒,這時候業務已經不可接收了。
  • 隊列中積攢1s之後,有多少個就寫入多少個,優點是時間可控,缺點就是values number數目不可能,高併發的情況,可能1s已經積攢上千個values了。
  • 最優的方案其實是2個條件同時起作用,即進行個數效驗,也進行時間效驗,無論達到那個條件都觸發後續寫資料庫操作。

總結:

1、使用batch insert可以提高insert的吞吐量。

2、疊加的values number需要根據實際情況測試得出。

3、同時使用個數和時間控制閥值。

 附簡單測試的記錄值:

ValuesNum

Time

QPS

Rows

1

1777

56

56

10

53

188

1886

50

49

40

2040

100

50

19

2000

200

51

10

1960

500

57

3

1754

1000

60

2

1666

5000

69

0.3

1449

10000

133

0.07

751


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 對於設計和創建資料庫完全是個新手?沒關係,Joe Celko,世界上讀者數量最多的SQL作者之一,會告訴你這些基礎。和往常一樣,即使是最專業的資料庫老手,也會給他們帶來驚喜。Joe是DMBS雜誌是多年來最受讀者喜愛的作者。他在美國、英國,北歐,南美及非洲傳授SQL知識。他在ANSI / ISO SQ ...
  • 1 數據表結構的設計與性能優化 1.1 、數據表的存儲原理 SQL Server每次讀取1個存儲塊,每個存儲塊大小為8KB,每讀取1個存儲塊計算為1個邏輯讀。 問題:如果數據內容非常大,像我們系統中的Feeling欄位非常大,就會導致每個存儲塊存放的數據行數會非常少,這樣當我們讀取數據時,要讀取許多 ...
  • MySQL資料庫伺服器的架設 MySQL資料庫伺服器的架設 MySQL資料庫伺服器的架設 導讀 MySQL資料庫是Linux操作系統上用得最多的資料庫系統,它可以非常方便的與其它伺服器集成在一起,如Apache、Vsftpd、Postfix等。下麵介紹RHEL 6平臺MySQL資料庫伺服器的安裝方法 ...
  • SQLServer 2012 Always on是針對高可用性和災難恢復的新解決方案。可以配置一個或多個輔助副本以支持對輔助資料庫進行只讀訪問,並且可以將任何輔助副本配置為允許對輔助資料庫進行備份。 這樣就提供了硬體的使用效率。 “可用性組”針對一組離散的用戶資料庫(稱為“可用性資料庫”,它們共同實 ...
  • 18 複製 18 複製... 1 18.1 複製配置... 3 18.1.1 基於Binary Log的資料庫複製配置... 3 18.1.2 配置基於Binary log的複製... 3 18.1.2.1 設置複製master的配置... 3 18.1.2.2 創建複製要用的用戶... 4 18. ...
  • 今天因為畢業設計要用到MySql資料庫,所以就準備自己安裝一個MySQL資料庫,但是因為MySQL Install MSI只有32位,所以最後選擇使用Windows (x86, 64-bit), ZIP Archive版的安裝使用,下麵本人來介紹自己安裝MySQL的過程,僅供參考。 添加完之後保存, ...
  • --查詢最慢的sql select * from (select parsing_user_id,executions,sortscommand_type,disk_reads,sql_text from v$sqlarea order by disk_reads desc)where rownum ...
  • 之前安裝過mysql、最近剛好要重新翻出來看看 發現又忘記了那些命令、還是要百度、所以不如自己整理下 儘管網上有很多相關的介紹、當時想對的不如自己整理出來的舒服 首先是下載安裝、網上有很多就不一一羅列了 首先是開啟服務命令: net start mysql 關閉服務命令: net stop mysq ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...