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

2021-05-27 11:26:51 字數 4754 閱讀 2202

insert語句的速度插入乙個記錄需要的時間由下列因素組成,其中的數字表示大約比例:

連線:(3)

傳送查詢給伺服器:(2)

分析查詢:(2)

插入記錄:(1x記錄大小)

插入索引:(1x索引)

關閉:(1)

這不考慮開啟表的初始開銷,每個併發執行的查詢開啟。

表的大小以logn (b樹)的速度減慢索引的插入。

加快插入的一些方法:

· 如果同時從同乙個客戶端插入很多行,使用含多個value的insert語句同時插入幾行。這比使用單行insert語句快(在某些情況下快幾倍)。如果你正向乙個非空表新增資料,可以調節bulk_insert_buffer_size變數,使資料插入更快。參見5.3.3節,「伺服器系統變數」。

· 如果你從不同的客戶端插入很多行,能通過insert delayed語句加快速度。參見13.2.4節,「insert語法」。

· 用myisam,如果在表中沒有刪除的行,能在select語句正在執行的同時插入行。

· 當從乙個文字檔案裝載乙個表時,使用load data infile。這通常比使用很多insert語句快20倍。參見13.2.5節,「load data infile語法」。

· 當表有很多索引時,有可能要多做些工作使得load data infile更快些。使用下列過程:

有選擇地用create table建立表。也可以使用alter table tbl_name disable keys代替myisamchk --keys-used=0 -rq/path/to/db/tbl_name,使用alter table tbl_name enable keys代替myisamchk -r -q/path/to/db/tbl_name。使用這種方式,還可以跳過flush tables。

· 鎖定表可以加速用多個語句執行的insert操作:

lock tables a write;

insert into a values (1,23),(2,34),(4,33);

insert into a values (8,26),(6,29);

unlock tables;

這樣效能會提高,因為索引快取區僅在所有insert語句完成後重新整理到磁碟上一次。一般有多少insert語句即有多少索引快取區重新整理。如果能用乙個語句插入所有的行,就不需要鎖定。

對於事務表,應使用begin和commit代替lock tables來加快插入。

鎖定也將降低多連線測試的整體時間,儘管因為它們等候鎖定最大等待時間將上公升。例如:

connection 1 does 1000 inserts

connections 2, 3, and 4 do 1 insert

connection 5 does 1000 inserts

如果不使用鎖定,2、3和4將在1和5前完成。如果使用鎖定,2、3和4將可能不在1或5前完成,但是整體時間應該快大約40%。

insert、update和delete操作在mysql中是很快的,通過為在一行中多於大約5次連續不斷地插入或更新的操作加鎖,可以獲得更好的整體效能。如果在一行中進行多次插入,可以執行lock tables,隨後立即執行unlock tables(大約每1000行)以允許其它的執行緒訪問表。這也會獲得好的效能。

insert裝載資料比load data infile要慢得多,即使是使用上述的策略。

· 為了對load data infile和insert在myisam表得到更快的速度,通過增加key_buffer_size系統變數來擴大 鍵高速緩衝區。參見7.5.2節,「調節伺服器引數」。

insert語法

insert [low_priority | delayed | high_priority] [ignore]

[into] tbl_name [(col_name,...)]

values (,...),(...),...

[ on duplicate key update col_name=expr, ... ]

或:insert [low_priority | delayed | high_priority] [ignore]

[into] tbl_name

set col_name=, ...

[ on duplicate key update col_name=expr, ... ]

或:insert [low_priority | high_priority] [ignore]

[into] tbl_name [(col_name,...)]

select ...

[ on duplicate key update col_name=expr, ... ]

一、delayed 的使用

使用延遲插入操作

delayed調節符應用於insert和replace語句。當delayed插入操作到達的時候,

伺服器把資料行放入乙個佇列中,並立即給客戶端返回乙個狀態資訊,這樣客戶

端就可以在資料表被真正地插入記錄之前繼續進行操作了。如果讀取者從該資料

表中讀取資料,佇列中的資料就會被保持著,直到沒有讀取者為止。接著伺服器

開始插入延遲資料行(delayed-row)佇列中的資料行。在插入操作的同時,伺服器

還要檢查是否有新的讀取請求到達和等待。如果有,延遲資料行佇列就被掛起,

允許讀取者繼續操作。當沒有讀取者的時候,伺服器再次開始插入延遲的資料行。

這個過程一直進行,直到佇列空了為止。

幾點要注意事項:

· insert delayed應該僅用於指定值清單的insert語句。伺服器忽略用於insert delayed...select語句的delayed。

· 伺服器忽略用於insert delayed...on duplicate update語句的delayed。

· 因為在行被插入前,語句立刻返回,所以您不能使用last_insert_id()來獲取auto_increment值。auto_increment值可能由語句生成。

· 對於select語句,delayed行不可見,直到這些行確實被插入了為止。

· delayed在從屬復**務器中被忽略了,因為delayed不會在從屬伺服器中產生與主伺服器不一樣的資料。

注意,目前在佇列中的各行只儲存在儲存器中,直到它們被插入到表中為止。這意味著,如果您強行中止了mysqld(例如,使用kill -9)

或者如果mysqld意外停止,則所有沒有被寫入磁碟的行都會丟失。

二、ignore的使用

ignore是mysql相對於標準sql的擴充套件。如果在新錶中有重複關鍵字,

或者當strict模式啟動後出現警告,則使用ignore控制alter table的執行。

如果沒有指定ignore,當重複關鍵字錯誤發生時,複製操作被放棄,返回前一步驟。

如果指定了ignore,則對於有重複關鍵字的行,只使用第一行,其它有衝突的行被刪除。

並且,對錯誤值進行修正,使之盡量接近正確值。

insert ignore into tb(...) value(...)

這樣不用校驗是否存在了,有則忽略,無則新增

三、on duplicate key update的使用

如果您指定了on duplicate key update,並且插入行後會導致在乙個unique索引或primary key中出現重複值,則執行舊行update。例如,如果列a被定義為unique,並且包含值1,則以下兩個語句具有相同的效果:

mysql> insert into table (a,b,c) values (1,2,3)

-> on duplicate key update c=c+1;

mysql> update table set c=c+1 where a=1;

如果行作為新記錄被插入,則受影響行的值為1;如果原有的記錄被更新,則受影響行的值為2。

注釋:如果列b也是唯一列,則insert與此update語句相當:

mysql> update table set c=c+1 where a=1 or b=2 limit 1;

如果a=1 or b=2與多個行向匹配,則只有乙個行被更新。通常,您應該盡量避免對帶有多個唯一關鍵字的表使用on duplicate key子句。

您可以在update子句中使用values(col_name)函式從insert…update語句的insert部分引用列值。換句話說,如果沒有發生重複關鍵字衝突,則update子句中的values(col_name)可以引用被插入的col_name的值。本函式特別適用於多行插入。values()函式只在insert…update語句中有意義,其它時候會返回null。

示例:

mysql> insert into table (a,b,c) values (1,2,3),(4,5,6)

-> on duplicate key update c=values(a)+values(b);

本語句與以下兩個語句作用相同:

mysql> insert into table (a,b,c) values (1,2,3)

-> on duplicate key update c=3;

mysql> insert into table (a,b,c) values (4,5,6)

-> on duplicate key update c=9;

當您使用on duplicate key update時,delayed選項被忽略。

SQL Server大資料量插入

sql server大資料插入方法比較多,下面我們先談談bulk insert 方法。首先,我們建立一張table,如下面t sql指令碼 create table testtable2 id int,amount int check amount 1000 and amount 5000 假設有這...

MySQL大資料量快速分頁實現

以下分享一點我的經驗 一般剛開始學sql語句的時候,會這樣寫 如下 select from table order by id limit 1000,10 但在資料達到百萬級的時候,這樣寫會慢死 如下 select from table order by id limit 1000000,10 也許...

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

專案背景 對mysql資料進行初始化加密 假設待加密表 表名student,列名a,擁有5000w資料量 這個方案缺陷在於,修改列 刪除列會重建表,給所有資料行新增一段資料,所以會導致資料量越大越耗時。如果無法繞過新增列,那麼就得使用online ddl,最大限度減少鎖的使用。使用方式 alter ...