MySQL效能優化大資料量插入資料

2021-09-27 00:10:03 字數 3649 閱讀 5692

專案背景:對mysql資料進行初始化加密

假設待加密表:表名student,列名a,擁有5000w資料量

這個方案缺陷在於,修改列、刪除列會重建表,給所有資料行新增一段資料,所以會導致資料量越大越耗時。

如果無法繞過新增列,那麼就得使用online ddl,最大限度減少鎖的使用。

使用方式:

alter table tbl_name add primary key (column), algorithm=inplace, lock=none;

具體內容詳見:官方詳解online ddl

測試結果:

資料量(萬)

新增列插入資料

刪除列總耗時

20047min

31min

56min

2h17min

500105min

81min

123min

5h15min

與上述不同的地方為:

新增一張副本表,用來作為密文儲存,其餘不再贅述。

初始資料加密不經過proxy,增量資料加密走proxy

測試結果:

資料量(萬)

總耗時200

0.5h

5001h9.5min

1000

2h38min

總結

總耗時減少2倍時間

新增列方案重建了3次表,相當於新增表的3倍時間,經專案組所有成員審核過後,新增表方案會丟失觸發器,其餘與加密前一致,所以綜合考慮選擇新增表方案。

至於觸發器丟失,如果可以獲取觸發器資訊,那麼選擇重新觸發器;如果不可以獲取觸發器資訊,那麼提示客戶:不允許加密擁有觸發器的表。

通過查閱資料,摘取有利於提公升效能的引數,將其列出。

[client]

port = 3306

socket = /var/lib/mysql/mysql.sock

[mysql.server]

pid-file = /var/lib/mysql/localhost.pid

[mysqld]

port = 3306

socket =/var/lib/mysql/mysql.sock

# 網路傳輸中一次訊息傳輸量的最大值。系統預設值 為1mb,最大值是1gb,必須設定1024的倍數。

# 因為後續我們在**中是使用preparestatement.addbatch(),單次傳輸的值會比較大,所以這個引數必須加大。

max_allowed_packet = 32m

# 緩衝池大小,只需要用innodb的話則可以設定它高達 70-80% 的可用記憶體。

innodb_buffer_pool_size = 5120m

innodb_buffer_pool_instances=3

innodb_additional_mem_pool_size = 1024m

innodb_log_files_in_group = 3

innodb_lock_wait_timeout = 120

# 重新整理日誌頻率

open_files_limit = 10240

back_log = 600

innodb_log_file_size=110m

# 連線數

max_connections = 3000

max_connect_errors = 6000

# 多執行緒

thread_cache_size = 300

thread_concurrency = 16

thread_stack = 192kb

innodb_write_io_threads = 32

innodb_purge_threads=1

# 重新整理髒頁頻率

innodb_max_dirty_pages_pct=90

wait_timeout=300

配置詳解:

innodb緩衝池相關配置

mysql效能優化

由單執行緒的插入,改為多連線多執行緒插入,偽**如下。

環境檢查;

建立加密前環境;

建立connection連線池;

建立執行緒池;

// 忽略外來鍵檢查

statement.

executeupdate

("set foreign_key_checks = 0");

// 忽略唯一性檢查

statement.

executeupdate

("set unique_checks = 0");

查詢資料;

while

(結果集)

}

通過在當前會話改動動態變數,取消檢查,可以降低插入前的約束,減少判斷,對效率明顯提公升。

具體內容詳見:官方詳解dynamic system variables(動態系統變數)

測試結果:

資料量(萬)

總耗時5000

3h48min

注:該結果是基於上述所有優化後的最終結果

總結

忽略外來鍵、唯一性檢查,減少mysql插入時的約束,純粹地進行插入操作。

使用簡單的執行緒池或者生產者消費者模式,最終目標都是讓mysql不停地插入,只有像流水線一樣,整體的效率才會上去。

最後總結

從最初的5000w預估50h都可能加密不完,到最後的3h43min加密完成,期間的解決思路是由大至小,由生產者到消費者。

2023年10月08日10:43:31 最新更新

mysql5.1.40版本的更新內容

當連線屬性cacheprepstmts和 useserverprepstmts都設定為 true且伺服器端準備好的語句都設定為不可緩衝時,發生記憶體洩漏 ,這導致準備好的語句無法被客戶端關閉,並且準備好的語句的數量不斷增加。

當發生上述記憶體洩漏時,它不會使connector / j失敗,因為當達到最大準備語句數時,connector / j切換為使用客戶端準備語句。但是,當 rewritebatchedstatements還設定為true時,則不會發生切換到客戶端預備語句的情況,並且當客戶端想要建立比預備語句多得多的預備語句時,connector / j丟擲mysqlsyntaxerrorexception(「 不能建立超過max_prepared_stmt_count語句 」)。允許的。

此修復程式糾正了準備語句的處理方式,從而避免了上述兩個問題。(缺陷號22954007,錯誤#80615)

使用伺服器端準備語句且使用批量形式,最大佔位符個數為65535

所以,最大執行語句=65535/字段數

由於以上限制,面對大字段數時,單次批量值下降,從而使得速度無法上公升。

那麼需要採用客戶端準備語句,但目前遇到乙個問題,客戶端準備語句精度丟失。

如果解決精度丟失問題,客戶端可以準備好語句,再傳送給服務端,減少服務端壓力。

MySQL大資料量分頁效能優化

mysql大資料量使用limit分頁,隨著頁碼的增大,查詢效率越低下。1.直接用limit start,count分頁語句,也是我程式中用的方法 select from product limit start,count 當起始頁較小時,查詢沒有效能問題,我們分別看下從10,100,1000,100...

MySQL大資料量分頁效能優化

1.直接用limit start,count分頁語句,也是我程式中用的方法 select from product limit start,count 當起始頁較小時,查詢沒有效能問題,我們分別看下從10,100,1000,10000開始分頁的執行時間 每頁取20條 如下 select from p...

MySql 大資料量快速插入和語句優化

insert語句的速度插入乙個記錄需要的時間由下列因素組成,其中的數字表示大約比例 連線 3 傳送查詢給伺服器 2 分析查詢 2 插入記錄 1x記錄大小 插入索引 1x索引 關閉 1 這不考慮開啟表的初始開銷,每個併發執行的查詢開啟。表的大小以logn b樹 的速度減慢索引的插入。加快插入的一些方法...