C 批量Insert效能優化方案

2021-07-25 02:27:37 字數 4338 閱讀 6143

近期遇到乙個多個sql檔案載入到sql server的效能問題。由於某種歷史原因,每個sql檔案中,都是insert into語句。這些語句執行起來,效能可優化空間不大,除非重新改寫整個sql語句的生成機制。

在研究此問題的過程中,了解到c#本身提供了sqlbulkcopy類,可實現批量資料匯入,頗有啟發。直接引用董斌的一篇檔案,可以參考。

原文內容如下:

在sql server 中插入一條資料使用insert語句,但是如果想要批量插入一堆資料的話,迴圈使用insert不僅效率低,而且會導致sql一系統效能問題。下面介紹sql server支援的兩種批量資料插入方法:bulk和錶值引數(table-valued parameters)。

執行下面的指令碼,建立測試

資料庫和錶值引數。

[c-sharp]view plain

copy

--create database  

create database bulktestdb;  

go  

use bulktestdb;  

go  

--create table  

create table bulktesttable(  

id int

primary key,  

username nvarchar(32),  

pwd varchar(16))  

go  

--create table valued  

create type bulkudt as table  

(id int

,  username nvarchar(32),  

pwd varchar(16))  

下面我們使用最簡單的insert語句來插入100萬條資料,**如下:

[c-sharp]view plain

copy

stopwatch sw = 

newstopwatch();  

sqlconnection sqlconn = new

sqlconnection(  

configurationmanager.connectionstrings["connstr"

].connectionstring);

//連線資料庫

sqlcommand sqlcomm = new

sqlcommand();  

sqlcomm.commandtext = string

.format(

"insert into bulktesttable(id,username,pwd)values(@p0,@p1,@p2)"

);//引數化sql

sqlcomm.parameters.add("@p0"

, sqldbtype.int);  

sqlcomm.parameters.add("@p1"

, sqldbtype.nvarchar);  

sqlcomm.parameters.add("@p2"

, sqldbtype.varchar);  

sqlcomm.commandtype = commandtype.text;  

sqlcomm.connection = sqlconn;  

sqlconn.open();  

try"

, count * multiply);  

sqlcomm.parameters["@p2"

].value = 

string

.format(

"pwd-"

, count * multiply);  

sw.start();  

sqlcomm.executenonquery();  

sw.stop();  

}  //每插入10萬條資料後,顯示此次插入所用時間

console.writeline(string

.format(

"elapsed time is  milliseconds"

, sw.elapsedmilliseconds));  

}  }  

catch

(exception ex)  

finally

console.readline();  

耗時圖如下:

由於執行過慢,才插入10萬條就耗時72390 milliseconds,所以我就手動強行停止了。

下面看一下使用bulk插入的情況:

bulk方法主要思想是通過在客戶端把資料都快取在table中,然後利用sqlbulkcopy一次性把table中的資料插入到資料庫

**如下:

[c-sharp]view plain

copy

public

static

void

bulktodb(datatable dt)  

catch

(exception ex)  

finally

}  public

static

datatable gettableschema()  

);  

return

dt;  

}  static

void

main(

string

args)  

", count * multiply);  

r[2] = string

.format(

"pwd-"

, count * multiply);  

dt.rows.add(r);  

}  sw.start();  

bulk.bulktodb(dt);  

sw.stop();  

console.writeline(string

.format(

"elapsed time is  milliseconds"

, sw.elapsedmilliseconds));  

}  console.readline();  

}  

耗時圖如下:

可見,使用bulk後,效率和效能明顯上公升。使用insert插入10萬資料耗時72390,而現在使用bulk插入100萬資料才耗時17583。

最後再看看使用錶值引數的效率,會另你大為驚訝的。

錶值引數是sql server 2008新特性,簡稱tvps。對於錶值引數不熟悉的朋友,可以參考最新的book online,我也會另外寫一篇關於錶值引數的部落格,不過此次不對錶值引數的概念做過多的介紹。言歸正傳,看**:

[c-sharp]view plain

copy

public

static

void

tablevaluedtodb(datatable dt)  

}  catch

(exception ex)  

finally

}  public

static

datatable gettableschema()  

);  

return

dt;  

}  static

void

main(

string

args)  

", count * multiply);  

r[2] = string

.format(

"pwd-"

, count * multiply);  

dt.rows.add(r);  

}  sw.start();  

tablevalued.tablevaluedtodb(dt);  

sw.stop();  

console.writeline(string

.format(

"elapsed time is  milliseconds"

, sw.elapsedmilliseconds));  

}  console.readline();  

}  

耗時圖如下:

比bulk還快5秒。

mysql 優化 insert 效能

mysql 的 insert 語句語法 insert into table field1 field2 values value1 value2 提高insert 效能的方法 1.一條sql語句插入多條資料 insert into insert table uid content type valu...

MySQL優化insert效能的方法示例

mysql效能優化 mysql效能優化就是通過合理安排資源,調整系統引數使mysql執行更快 更節省資源。mysql效能優化包括查詢速度優化 更新速度優化 mysql伺服器優化等。本篇部落格將從查詢優化 資料庫結構優化 mysql伺服器優化3個方面介紹。mysql資料庫優化,一方面是找出系統瓶頸,提...

Lustre效能優化方案

部落格公告 1 本部落格所有部落格文章搬遷至 部落格蟲 網路頻寬往往決定著lustre檔案系統的聚合頻寬。lustre是通過多個oss同時讀取資料來提高系統整體的讀寫效能,然而,如果網路傳輸的效能過低,則無法發揮lustre檔案系統的效能優勢。從以下幾點考慮網路頻寬對效能的影響 網路型別 tcp i...