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

批量寫庫操作,如何優(yōu)化?

數(shù)據(jù)庫 SQL Server
涉及到SQL層和存儲層,其中SQL層需要解析SQL語句,生成抽象語法樹(AST),計算表達式等,存儲層需要判斷主鍵沖突,包括增量數(shù)據(jù)和基線數(shù)據(jù)上的主鍵沖突,如果是非重復主鍵,則將數(shù)據(jù)插入到增量數(shù)據(jù)中。

引言

數(shù)據(jù)庫插入操作的語句如下:

insert into table values (a1, b1)

涉及到SQL層和存儲層,其中SQL層需要解析SQL語句,生成抽象語法樹(AST),計算表達式等,存儲層需要判斷主鍵沖突,包括增量數(shù)據(jù)和基線數(shù)據(jù)上的主鍵沖突,如果是非重復主鍵,則將數(shù)據(jù)插入到增量數(shù)據(jù)中。

上條插入語句只插入一行數(shù)據(jù),稱之為單條插入,相應地,還可以在一條語句中插入多行數(shù)據(jù),稱之為批量插入。

insert into table values (a1, b1), (a2, b2), (a3, b3)

批量插入的多行數(shù)據(jù)作為一個事務,所有數(shù)據(jù)插入成功,或者所有數(shù)據(jù)插入失敗,不會出現(xiàn)部分數(shù)據(jù)插入成功的情況。批量插入相對于單條插入在性能上有很大優(yōu)勢,SQL解析只需要做一次,事務只需要做一次,因此理應在相同的時間內(nèi)插入更多行數(shù)據(jù)。

1. 單行插入引擎

此前,OceanBase的單條插入與批量插入使用的是同一套接口,從SQL層讀取一行,檢查沖突,插入數(shù)據(jù),然后反復重復這個過程,直到?jīng)]有數(shù)據(jù)為止。這樣的代碼看起來非常優(yōu)雅,卻沒有利用到批量插入的特點而做針對性的優(yōu)化。

2. 批量插入引擎

批量插入引擎每次可以讀取一批數(shù)據(jù),比如500行,然后做批量檢查沖突,再批量插入到增量數(shù)據(jù)中(內(nèi)存B+樹),目前做的只有批量讀和檢查沖突,批量插入留到以后再做??此坪芎唵蔚膬?yōu)化,性能卻提升了很多,在遞增插入場景,Sysbench bulk insert的單線程測試中,無基線數(shù)據(jù)時,性能提升30%,有基線數(shù)據(jù)時,性能提升了100%。性能提升的原因有如下幾點:

2.1 系統(tǒng)層面

  1. 正在處理的一批數(shù)據(jù)可以始終在CPU Cache中,L1 Cache的大小是32KB,一行的大小為32 bytes(元數(shù)據(jù),指針等),可以存儲1024行,而讀L1 Cache的性能是讀內(nèi)存性能的100倍。
  2. CPU不僅可以Cache數(shù)據(jù),還可以Cache指令,在單條插入的時候,在一定時間內(nèi)總是執(zhí)行不同的指令,因此很難Cache,每次都需要從內(nèi)存中取指令,將指令解碼后,才能再去取數(shù)據(jù),而在批量插入中,在一個緊湊的循環(huán)中,每次都是執(zhí)行相同的指令,因此這些指令基本上可以在Cache中。
  3. CPU訪問內(nèi)存的過程為,進程的虛擬內(nèi)存地址通過查找TLB(硬件高速緩存,空間較小),Page Table(內(nèi)存中)轉化為內(nèi)存的物理地址,若TLB中找不到對應的虛擬地址,需要訪問內(nèi)存中的Page Table。若同時處理一個500行的數(shù)組,TLB的命中率會大很多,而訪問TLB的速度是內(nèi)存的100倍。
  4. CPU有預取內(nèi)存功能,當從SQL中讀到的行需要轉換為存儲層中的行時,以前是讀內(nèi)存,轉換,讀內(nèi)存,轉換,而現(xiàn)在是完全并行起來的,轉換完一行之后,后面的行已經(jīng)從內(nèi)存中被預取到CPU Cache中了,而且CPU讀內(nèi)存的單位是Cache Line是64 bytes,每次可以讀兩行,而以前單行處理的時候,是把這個能力浪費了的。
  5. 存儲層從SQL拿數(shù)據(jù)的時候,會調(diào)用一個虛函數(shù)get_next_row,C++里虛函數(shù)是通過虛函數(shù)表實現(xiàn)的,對象里有一個指向虛函數(shù)表的指針,每次調(diào)用函數(shù)的時候,需要通過指針找到這個表,然后在表里再通過一個指針,找到相應的函數(shù)實現(xiàn),也就是每次調(diào)用get_next_row都有兩次隨機內(nèi)存訪問,而改成批量之后,就少了大量的這種操作,比如有4萬行數(shù)據(jù),以前需要4萬次虛函數(shù)調(diào)用,而現(xiàn)在只需要80次。

2.2 算法層面

  1. 檢查主鍵沖突的時候,由于基線數(shù)據(jù)是靜態(tài)的,最大值不變,而后面插入的數(shù)據(jù)往往是越來越大的,因此只需要比較一下這一批數(shù)據(jù)的最小值和靜態(tài)數(shù)據(jù)的最大值即可,減少了大量的沖突檢測。
  2. 單行插入內(nèi)存B+樹時,每一行都需要從根節(jié)點搜索,直到相應的葉子節(jié)點,需要多次加讀鎖寫鎖,批量插入后,對一批數(shù)據(jù)做一個排序,然后將相應的數(shù)據(jù)直接插入到相應的葉子節(jié)點而不再從根節(jié)點搜索,減少了大量的比較和加鎖操作,而且同一批數(shù)據(jù)基本在少量的葉子節(jié)點中,因此葉子節(jié)點基本都可以在CPU Cache中。

責任編輯:華軒 來源: 架構精進之路
相關推薦

2023-12-18 16:07:15

2010-05-31 17:18:39

Cassandra數(shù)據(jù)

2011-08-04 18:00:47

SQLite數(shù)據(jù)庫批量數(shù)據(jù)

2020-11-23 10:50:27

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

2013-09-22 10:25:23

MySQLSQL性能優(yōu)化

2018-08-09 08:59:56

數(shù)據(jù)庫MySQL性能優(yōu)化

2009-09-27 14:33:01

Hibernate批量

2010-11-29 13:17:00

Sybase批量操作

2018-03-28 09:26:43

數(shù)據(jù)庫緩存層優(yōu)化

2009-02-18 08:36:17

專家Windows優(yōu)化

2011-08-15 15:53:51

SQL Server數(shù)批量操作

2010-05-31 16:17:56

MySQL數(shù)據(jù)庫性能

2010-06-02 13:58:30

MySQL數(shù)據(jù)庫性能

2020-10-06 18:57:14

PostgreSQL數(shù)據(jù)庫數(shù)據(jù)導入

2017-09-08 15:20:13

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

2020-05-25 15:17:11

Python安裝的庫方法

2020-12-18 10:40:00

ExcelJava代碼

2022-07-15 11:33:01

供應鏈VR虛擬現(xiàn)實

2010-06-01 12:51:23

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

2022-03-02 09:01:07

CPU使用率優(yōu)化
點贊
收藏

51CTO技術棧公眾號