32 个解决方案
#1
相应的sql语句如下(ROWTERMINATOR对应设置的是行尾字符):
BULK INSERT 目标表名 from 'txt源文件名' WITH (FIRSTROW=1,ROWTERMINATOR = '\n');
BULK INSERT 目标表名 from 'txt源文件名' WITH (FIRSTROW=1,ROWTERMINATOR = '\n');
#2
学习,还有这种方法
#3
[另类解]文本文件快速导入到MS SQL server 僵哥/mg/fad
07.23 01:31
返回群论坛
要提高速度就尽可能减少对数据库的访问,即以一次提交多笔的方式进行提交,当然,若是能够直接以Socket的方式传输,或许会更快,这或许也就是为什么ms的bcp之类的能高速度执行对ms sql的数据导入的原因之一吧。
举个例说吧:
1.测试一:
==================================
==================================
2.测试二
==================================
分别执行这两段代码往数据库当中写入20万条记录,测试二当中大概的花费依机器配置情况,大概为2~5分钟,甚至更短,测试一当中时间的花费,将会远远超过测试二。
以前写的代码:
07.23 01:31
返回群论坛
要提高速度就尽可能减少对数据库的访问,即以一次提交多笔的方式进行提交,当然,若是能够直接以Socket的方式传输,或许会更快,这或许也就是为什么ms的bcp之类的能高速度执行对ms sql的数据导入的原因之一吧。
举个例说吧:
1.测试一:
==================================
DWORD StartTime=GetTickCount();
for( int i=0;i<200000;i++)
{
ADOCommand->CommandText="Insert into tablename (field1,field2,field3[...,fieldn]) values(value1,value2,value3[...,valuen])";
ADOCommand->Execute();
}
DWORD EndTime=GetTickCount();
ShowMessage((int)(EndTime-StartTime));
==================================
2.测试二
==================================
const AnsiString SplitEmpty="",Split=";";
DWORD StartTime=GetTickCount();
int Count,iCacheSize=1000;
TStringList *CacheList=new TStringList();
try
{
for(int i=0;i<200000;i++)
{
if(Count)
CacheList->Add(";Insert into tablename (field1,field2,field3[...,fieldn]) values(value1,value2,value3[...,valuen])");
else
CacheList->Add("Insert into tablename (field1,field2,field3[...,fieldn]) values(value1,value2,value3[...,valuen])");
Count++;
if(Count==iCacheSize)
{
ADOCommand->CommandText=CacheList->Text;
CacheList->Clear();
Count=0;
ADOCommand->Execute();
}
}
if(Count>0)
{
ADOCommand->CommandText=CacheList->Text;
ADOCommand->Execute();
}
}
__finally
{
CacheList->Free();
}
DWORD EndTime=GetTickCount();
ShowMessage((int)(EndTime-StartTime));
==================================
分别执行这两段代码往数据库当中写入20万条记录,测试二当中大概的花费依机器配置情况,大概为2~5分钟,甚至更短,测试一当中时间的花费,将会远远超过测试二。
以前写的代码:
void __fastcall TForm1::Edit1KeyPress(TObject *Sender, char &Key)
{
if(Key>'9'||Key<'0')
Key='\0';
}
//---------------------------------------------------------------------------
void __fastcall TForm1::cmdCreateFileClick(TObject *Sender)
{
DWORD StartAt=GetTickCount();
AnsiString InputString=Edit6->Text;
InputString+="\r\n";
unsigned int Counter=StrToInt(Edit2->Text);
FILE *fp=fopen(Edit5->Text.c_str(),"w");
try
{
while(1<(Counter--))
fwrite(InputString.c_str(),InputString.Length(),1,fp);
fwrite(Edit6->Text.c_str(),Edit6->Text.Length(),1,fp);
}
__finally
{
fclose(fp);
}
DWORD EndAt=GetTickCount();
StatusBar1->Panels->Items[0]->Text="创建文件耗时"+IntToStr(EndAt-StartAt)+"毫秒";
}
//---------------------------------------------------------------------------
void __fastcall TForm1::cmdRunClick(TObject *Sender)
{
const AnsiString Split=";",SplitEmpty="";
AnsiString taskid= Edit1->Text;
AnsiString fd2=Edit3->Text;
AnsiString context=Edit4->Text;
char buf[1025];
if(!FileExists(Edit5->Text))
cmdCreateFile->Click();
TDateTime dtStart=Now();
StatusBar1->Panels->Items[1]->Text=TimeToStr(dtStart)+"正在执行...";
DWORD StartAt=GetTickCount();
ADOCommand1->ConnectionString=Edit7->Text;
unsigned int CurrentRows=0;
unsigned int CacheRows=StrToInt(Edit8->Text);
HANDLE hFile=CreateFile(Edit5->Text.c_str(),
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0);
if(hFile==INVALID_HANDLE_VALUE)
{
StatusBar1->Panels->Items[1]->Text="打开文件["+Edit5->Text+"]失败!";
return;
}
try
{
DWORD dwSizeL,dwSizeH;
dwSizeL=GetFileSize(hFile,&dwSizeH);
unsigned __int64 i64Size=dwSizeH;
i64Size<<=32;
i64Size+=dwSizeL;
SetFilePointer(hFile,
0,
NULL,
FILE_BEGIN);
DWORD SizeBeRead;
TStringList *tls=new TStringList();
try
{
while(i64Size>0)
{
SizeBeRead=1024;
if(i64Size<SizeBeRead)
SizeBeRead=i64Size;
memset(buf,0,1025);
ReadFile(hFile,
buf,
SizeBeRead,
&SizeBeRead,
NULL);
i64Size-=SizeBeRead;
int Index=0;
int nIndex=0;
char* c=buf;
while(Index<1024)
{
if(buf[Index]=='\0')
break;
if(buf[Index]=='\n')
{
buf[Index]='\0';
if(Index>0)
if(buf[Index-1]=='\r')
buf[Index-1]='\0';
if(Index>1)
if(buf[Index-2]=='\r')
buf[Index-2]='\0';
tls->Add((CurrentRows>0?Split:SplitEmpty)+
"insert into test (id,fed1,fd2,context,state) values("+
taskid+",'"+AnsiString(c)+"','"+fd2+"','"+context+"',0)");
CurrentRows++;
if(CurrentRows==CacheRows)
{
ADOCommand1->CommandText=tls->Text;
ADOCommand1->Execute();
tls->Clear();
CurrentRows=0;
}
c+=Index-nIndex;
nIndex=Index;
nIndex++;
c++;
}
Index++;
}
if(i64Size<=0)
{
tls->Add((CurrentRows>0?Split:SplitEmpty)+
"insert into test (id,fed1,fd2,context,state) values("+
taskid+",'"+AnsiString(c)+"','"+fd2+"','"+context+"',0)");
CurrentRows++;
}
else
{
nIndex=nIndex-1024;
SetFilePointer(hFile,
nIndex,
NULL,
FILE_CURRENT);
i64Size-=nIndex;
}
}
if(CurrentRows>0)
{
ADOCommand1->CommandText=tls->Text;
ADOCommand1->Execute();
tls->Clear();
CurrentRows=0;
}
}
__finally
{
tls->Free();
}
}
__finally
{
CloseHandle(hFile);
}
DWORD EndAt=GetTickCount();
TDateTime dtEnd=Now();
StatusBar1->Panels->Items[1]->Text="("+TimeToStr(dtStart)+"-"+TimeToStr(dtEnd)+")执行过程耗时"+IntToStr(EndAt-StartAt)+"毫秒";
}
//---------------------------------------------------------------------------
#4
"胡一刀"
的试了不行的
的试了不行的
#5
僵哥写的 测试二
我已经用过了
但是同时插入10万条记录以上 超慢 有时还死机
我已经用过了
但是同时插入10万条记录以上 超慢 有时还死机
#6
直接将txt数据文件倒入数据库(远程) 如何做 EXEC 等外壳试过了不行 BULK Insert 也不行 提示找不到txt文件
#7
超慢,还死机?不知道你的机器为什么会这样.
#8
我这里有个测试需求是将100万个账号(每个12字节,每行一个账号,存储于文本文件当中),输入到数据库当中.有空我测一下发结果上来.
#9
哈哈,我笑了!学习下!
#10
等待中。。。。。
#11
僵哥的测试二 是在理想状态下的测试(只有单纯的插入数据) 现实中数据的获取也要花费相当的时间 这样 总时间就会很长 如果获取数据的方式不对 会耗费大量的cpu时间片 这样会大大影响数据的插入
#12
先將Txt文件轉爲Excel格式文件,然後將Excel導入數據庫。
#13
BULK Insert
TXT 文件要上傳致到 SQL Server 服務器上。不要放在客戶端上。
僵哥写的 测试二 速度應該還是很快的。
BULK Insert 方案,因為要生成TXT文件並將文件上傳至服務器中,完成速度與"测试二"相比要看網絡情況與記錄數多少,一般情況下BULK Insert方案總體快些。"测试二"則為標准SQL語法,比BULK Insert 或(Insert into + OpenRowSet方式)通用。
先將Txt文件轉爲Excel格式文件,然後將Excel導入數據庫。這樣不如直接導入TXT文本。
TXT 文件要上傳致到 SQL Server 服務器上。不要放在客戶端上。
僵哥写的 测试二 速度應該還是很快的。
BULK Insert 方案,因為要生成TXT文件並將文件上傳至服務器中,完成速度與"测试二"相比要看網絡情況與記錄數多少,一般情況下BULK Insert方案總體快些。"测试二"則為標准SQL語法,比BULK Insert 或(Insert into + OpenRowSet方式)通用。
先將Txt文件轉爲Excel格式文件,然後將Excel導入數據庫。這樣不如直接導入TXT文本。
#14
"测试二"使用ADOComand遞交數據, 比使用DBX的TSQLConnection慢.
String SQL ;
TSQLConnection *SQLConn;
//---------------
DWORD StartAt=GetTickCount();
SQLConn->StartTransaction(TransactionDesc);
try{
for(int i = 0 ; i< 10*1000*1000; ++i) { //共提交10M次
SQL.Clear();
for(int i = 0 ; i < 10 ; ++i) //每次插入 10 行
SQL += "insert into TableA(Field0) Values('test data')\n";
SQLConnection->ExecuteDirect(SQL);
}
SQLConn->Commit(TransactionDesc);
}
catch(Exception &E){
SQLConn->Rollback(TransactionDesc);
throw Exception(E.Message);
}
catch(...){
SQLConn->Rollback(TransactionDesc);
throw Exception(String("unknow error"));
}
DWORD EndTime=GetTickCount();
ShowMessage((int)(EndTime-StartTime));
改用TSQLConnection ,使用 並將 iCacheSize= 10 ~ 100 ; 速度估計至少提升 10% .
String SQL ;
TSQLConnection *SQLConn;
//---------------
DWORD StartAt=GetTickCount();
SQLConn->StartTransaction(TransactionDesc);
try{
for(int i = 0 ; i< 10*1000*1000; ++i) { //共提交10M次
SQL.Clear();
for(int i = 0 ; i < 10 ; ++i) //每次插入 10 行
SQL += "insert into TableA(Field0) Values('test data')\n";
SQLConnection->ExecuteDirect(SQL);
}
SQLConn->Commit(TransactionDesc);
}
catch(Exception &E){
SQLConn->Rollback(TransactionDesc);
throw Exception(E.Message);
}
catch(...){
SQLConn->Rollback(TransactionDesc);
throw Exception(String("unknow error"));
}
DWORD EndTime=GetTickCount();
ShowMessage((int)(EndTime-StartTime));
改用TSQLConnection ,使用 並將 iCacheSize= 10 ~ 100 ; 速度估計至少提升 10% .
#15
先谢了 我先试试!!
#16
具体点
#17
用事务 估计慢
#18
MySQL有专门的读取语句,可以把文本文件中的数据读入数据库,比用insert快太多了
#19
需要获取数据,那是获取数据所消耗的时间,我所说的只是让数据库操作的时间尽可能少.
其实PPower说的使用DBX的TSQLConnection会比ADO操作快,这一点个人并不赞同.我没有做过实际的测试,所以无法下最终的结论.但是从理论上来讲,DBX也是需要通过ADO操作的,所以它的快只在于连接池的使用.对于单线程的程序来讲,可能在表面上看是会有所提升,但是这个并不能说明实质性的问题.
对于这种操作,个人建议是使用显示的事务,即强制每一批提交一个事务.对于支持事务的DBMS,并不会因为你没有显示使用事务,它就不会使用事务.只是这个事务是由DBMS自己去控制.
#20
MSSQL也有类似的,关键看源数据的格式等等.为什么你会觉得比使用insert快,只是因为很多细节由数据库系统内部进行控制和优化过了.类似的数据库系统,内部仍然还是一条条insert.
#21
如果是mssql,用bulk insert肯定是最快的,应该不会不行的啊,你试试建个文本文档到d盘下的0.txt,里面输入几行字符,然后执行:
BULK INSERT test from 'e:\0.txt' WITH (FIRSTROW=1,ROWTERMINATOR = '\n');
(test表只有一列varchar类型)
你那个提示找不到txt文件应该是路径没写对
BULK INSERT test from 'e:\0.txt' WITH (FIRSTROW=1,ROWTERMINATOR = '\n');
(test表只有一列varchar类型)
你那个提示找不到txt文件应该是路径没写对
#22
1.buld insert如果没有记错的话,文件需要在数据库的本地磁盘;
2.输出到文件也是需要消耗时间的.
#23
晕,又打错...
#24
To unsigned :
在使用事務的情況下,我的實測結果是DBX比ADO快不少。
沒測試過不用事務的情況。(DBX4 + MSSQL)
(測試時,第一次遞交數據因為服務器要擴張表空間,這時間太多因素影響,所以要忽略。每次測試前清空表再插入數據。)
以下是偽代碼:
StartTransaction
delete table
for(int i = 0 ; i < 10*1000*1000 ++i)
Execute(SQL,...);
Commit
同樣過程,DBX優於ADO即:
SQLConnection->ExecuteDirect(SQL);
優於
ADOConnection->Execute(SQL,
cmdTex,TExecuteOptions() << eoExecuteNoRecords); //可能是我選擇的參數不對。沒測試其他參數。
不清楚DBX4的MSSQL驅動是什麼方式與MSSQL交互的?
在使用事務的情況下,我的實測結果是DBX比ADO快不少。
沒測試過不用事務的情況。(DBX4 + MSSQL)
(測試時,第一次遞交數據因為服務器要擴張表空間,這時間太多因素影響,所以要忽略。每次測試前清空表再插入數據。)
以下是偽代碼:
StartTransaction
delete table
for(int i = 0 ; i < 10*1000*1000 ++i)
Execute(SQL,...);
Commit
同樣過程,DBX優於ADO即:
SQLConnection->ExecuteDirect(SQL);
優於
ADOConnection->Execute(SQL,
cmdTex,TExecuteOptions() << eoExecuteNoRecords); //可能是我選擇的參數不對。沒測試其他參數。
不清楚DBX4的MSSQL驅動是什麼方式與MSSQL交互的?
#25
呃...僵哥说的很详细恶劣
#26
对 用 buld insert 只有在本地磁盘 上可以操作
关键是 要解决 远程操作的问题 用的是 ms sql
#27
如果是远程共享的文件夹,用bulk insert并无问题,我已进行了测试,是可以的:
BULK INSERT test from '\\192.168.0.1\Share\0.txt' WITH (FIRSTROW=1,ROWTERMINATOR = '\n');
BULK INSERT test from '\\192.168.0.1\Share\0.txt' WITH (FIRSTROW=1,ROWTERMINATOR = '\n');
#28
不知道文本数据需要加工不?是不是规则的。
可以考虑如下方式:
给DTS包传递参数,支持的参数包括(环境变量、注册表值和参数字符)判断后,导入数据。用VBScript、JScript 编程,完成数据的判断和转换任务。
速度比较快。
可以考虑如下方式:
给DTS包传递参数,支持的参数包括(环境变量、注册表值和参数字符)判断后,导入数据。用VBScript、JScript 编程,完成数据的判断和转换任务。
速度比较快。
#29
见识
#30
谢谢该结贴了
#31
插入數據庫有個能提高效率的寫法
insert into table(field1,field2) values(value1, value2) values(value3,value4) values(value5,value6)....
現在程序裏把所有的value拼在一起 然後一起insert
這中間省去了很多時間 試一下看看
insert into table(field1,field2) values(value1, value2) values(value3,value4) values(value5,value6)....
現在程序裏把所有的value拼在一起 然後一起insert
這中間省去了很多時間 試一下看看
#32
更正 以上方法 在Sql Server中似乎不能跑
在mySql裏是可以這樣寫的 把多句合併成一句
insert into table(field) values(value1)
insert into table(field) values(value2)
insert into table(field) values(value3)
insert into table(field) values(value4)
insert into table(field) values(value5)
合併成
insert into table(field) values(value1),(value2),(value3),(value4),(value5)
在mySql裏是可以這樣寫的 把多句合併成一句
insert into table(field) values(value1)
insert into table(field) values(value2)
insert into table(field) values(value3)
insert into table(field) values(value4)
insert into table(field) values(value5)
合併成
insert into table(field) values(value1),(value2),(value3),(value4),(value5)
#1
相应的sql语句如下(ROWTERMINATOR对应设置的是行尾字符):
BULK INSERT 目标表名 from 'txt源文件名' WITH (FIRSTROW=1,ROWTERMINATOR = '\n');
BULK INSERT 目标表名 from 'txt源文件名' WITH (FIRSTROW=1,ROWTERMINATOR = '\n');
#2
学习,还有这种方法
#3
[另类解]文本文件快速导入到MS SQL server 僵哥/mg/fad
07.23 01:31
返回群论坛
要提高速度就尽可能减少对数据库的访问,即以一次提交多笔的方式进行提交,当然,若是能够直接以Socket的方式传输,或许会更快,这或许也就是为什么ms的bcp之类的能高速度执行对ms sql的数据导入的原因之一吧。
举个例说吧:
1.测试一:
==================================
==================================
2.测试二
==================================
分别执行这两段代码往数据库当中写入20万条记录,测试二当中大概的花费依机器配置情况,大概为2~5分钟,甚至更短,测试一当中时间的花费,将会远远超过测试二。
以前写的代码:
07.23 01:31
返回群论坛
要提高速度就尽可能减少对数据库的访问,即以一次提交多笔的方式进行提交,当然,若是能够直接以Socket的方式传输,或许会更快,这或许也就是为什么ms的bcp之类的能高速度执行对ms sql的数据导入的原因之一吧。
举个例说吧:
1.测试一:
==================================
DWORD StartTime=GetTickCount();
for( int i=0;i<200000;i++)
{
ADOCommand->CommandText="Insert into tablename (field1,field2,field3[...,fieldn]) values(value1,value2,value3[...,valuen])";
ADOCommand->Execute();
}
DWORD EndTime=GetTickCount();
ShowMessage((int)(EndTime-StartTime));
==================================
2.测试二
==================================
const AnsiString SplitEmpty="",Split=";";
DWORD StartTime=GetTickCount();
int Count,iCacheSize=1000;
TStringList *CacheList=new TStringList();
try
{
for(int i=0;i<200000;i++)
{
if(Count)
CacheList->Add(";Insert into tablename (field1,field2,field3[...,fieldn]) values(value1,value2,value3[...,valuen])");
else
CacheList->Add("Insert into tablename (field1,field2,field3[...,fieldn]) values(value1,value2,value3[...,valuen])");
Count++;
if(Count==iCacheSize)
{
ADOCommand->CommandText=CacheList->Text;
CacheList->Clear();
Count=0;
ADOCommand->Execute();
}
}
if(Count>0)
{
ADOCommand->CommandText=CacheList->Text;
ADOCommand->Execute();
}
}
__finally
{
CacheList->Free();
}
DWORD EndTime=GetTickCount();
ShowMessage((int)(EndTime-StartTime));
==================================
分别执行这两段代码往数据库当中写入20万条记录,测试二当中大概的花费依机器配置情况,大概为2~5分钟,甚至更短,测试一当中时间的花费,将会远远超过测试二。
以前写的代码:
void __fastcall TForm1::Edit1KeyPress(TObject *Sender, char &Key)
{
if(Key>'9'||Key<'0')
Key='\0';
}
//---------------------------------------------------------------------------
void __fastcall TForm1::cmdCreateFileClick(TObject *Sender)
{
DWORD StartAt=GetTickCount();
AnsiString InputString=Edit6->Text;
InputString+="\r\n";
unsigned int Counter=StrToInt(Edit2->Text);
FILE *fp=fopen(Edit5->Text.c_str(),"w");
try
{
while(1<(Counter--))
fwrite(InputString.c_str(),InputString.Length(),1,fp);
fwrite(Edit6->Text.c_str(),Edit6->Text.Length(),1,fp);
}
__finally
{
fclose(fp);
}
DWORD EndAt=GetTickCount();
StatusBar1->Panels->Items[0]->Text="创建文件耗时"+IntToStr(EndAt-StartAt)+"毫秒";
}
//---------------------------------------------------------------------------
void __fastcall TForm1::cmdRunClick(TObject *Sender)
{
const AnsiString Split=";",SplitEmpty="";
AnsiString taskid= Edit1->Text;
AnsiString fd2=Edit3->Text;
AnsiString context=Edit4->Text;
char buf[1025];
if(!FileExists(Edit5->Text))
cmdCreateFile->Click();
TDateTime dtStart=Now();
StatusBar1->Panels->Items[1]->Text=TimeToStr(dtStart)+"正在执行...";
DWORD StartAt=GetTickCount();
ADOCommand1->ConnectionString=Edit7->Text;
unsigned int CurrentRows=0;
unsigned int CacheRows=StrToInt(Edit8->Text);
HANDLE hFile=CreateFile(Edit5->Text.c_str(),
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0);
if(hFile==INVALID_HANDLE_VALUE)
{
StatusBar1->Panels->Items[1]->Text="打开文件["+Edit5->Text+"]失败!";
return;
}
try
{
DWORD dwSizeL,dwSizeH;
dwSizeL=GetFileSize(hFile,&dwSizeH);
unsigned __int64 i64Size=dwSizeH;
i64Size<<=32;
i64Size+=dwSizeL;
SetFilePointer(hFile,
0,
NULL,
FILE_BEGIN);
DWORD SizeBeRead;
TStringList *tls=new TStringList();
try
{
while(i64Size>0)
{
SizeBeRead=1024;
if(i64Size<SizeBeRead)
SizeBeRead=i64Size;
memset(buf,0,1025);
ReadFile(hFile,
buf,
SizeBeRead,
&SizeBeRead,
NULL);
i64Size-=SizeBeRead;
int Index=0;
int nIndex=0;
char* c=buf;
while(Index<1024)
{
if(buf[Index]=='\0')
break;
if(buf[Index]=='\n')
{
buf[Index]='\0';
if(Index>0)
if(buf[Index-1]=='\r')
buf[Index-1]='\0';
if(Index>1)
if(buf[Index-2]=='\r')
buf[Index-2]='\0';
tls->Add((CurrentRows>0?Split:SplitEmpty)+
"insert into test (id,fed1,fd2,context,state) values("+
taskid+",'"+AnsiString(c)+"','"+fd2+"','"+context+"',0)");
CurrentRows++;
if(CurrentRows==CacheRows)
{
ADOCommand1->CommandText=tls->Text;
ADOCommand1->Execute();
tls->Clear();
CurrentRows=0;
}
c+=Index-nIndex;
nIndex=Index;
nIndex++;
c++;
}
Index++;
}
if(i64Size<=0)
{
tls->Add((CurrentRows>0?Split:SplitEmpty)+
"insert into test (id,fed1,fd2,context,state) values("+
taskid+",'"+AnsiString(c)+"','"+fd2+"','"+context+"',0)");
CurrentRows++;
}
else
{
nIndex=nIndex-1024;
SetFilePointer(hFile,
nIndex,
NULL,
FILE_CURRENT);
i64Size-=nIndex;
}
}
if(CurrentRows>0)
{
ADOCommand1->CommandText=tls->Text;
ADOCommand1->Execute();
tls->Clear();
CurrentRows=0;
}
}
__finally
{
tls->Free();
}
}
__finally
{
CloseHandle(hFile);
}
DWORD EndAt=GetTickCount();
TDateTime dtEnd=Now();
StatusBar1->Panels->Items[1]->Text="("+TimeToStr(dtStart)+"-"+TimeToStr(dtEnd)+")执行过程耗时"+IntToStr(EndAt-StartAt)+"毫秒";
}
//---------------------------------------------------------------------------
#4
"胡一刀"
的试了不行的
的试了不行的
#5
僵哥写的 测试二
我已经用过了
但是同时插入10万条记录以上 超慢 有时还死机
我已经用过了
但是同时插入10万条记录以上 超慢 有时还死机
#6
直接将txt数据文件倒入数据库(远程) 如何做 EXEC 等外壳试过了不行 BULK Insert 也不行 提示找不到txt文件
#7
超慢,还死机?不知道你的机器为什么会这样.
#8
我这里有个测试需求是将100万个账号(每个12字节,每行一个账号,存储于文本文件当中),输入到数据库当中.有空我测一下发结果上来.
#9
哈哈,我笑了!学习下!
#10
等待中。。。。。
#11
僵哥的测试二 是在理想状态下的测试(只有单纯的插入数据) 现实中数据的获取也要花费相当的时间 这样 总时间就会很长 如果获取数据的方式不对 会耗费大量的cpu时间片 这样会大大影响数据的插入
#12
先將Txt文件轉爲Excel格式文件,然後將Excel導入數據庫。
#13
BULK Insert
TXT 文件要上傳致到 SQL Server 服務器上。不要放在客戶端上。
僵哥写的 测试二 速度應該還是很快的。
BULK Insert 方案,因為要生成TXT文件並將文件上傳至服務器中,完成速度與"测试二"相比要看網絡情況與記錄數多少,一般情況下BULK Insert方案總體快些。"测试二"則為標准SQL語法,比BULK Insert 或(Insert into + OpenRowSet方式)通用。
先將Txt文件轉爲Excel格式文件,然後將Excel導入數據庫。這樣不如直接導入TXT文本。
TXT 文件要上傳致到 SQL Server 服務器上。不要放在客戶端上。
僵哥写的 测试二 速度應該還是很快的。
BULK Insert 方案,因為要生成TXT文件並將文件上傳至服務器中,完成速度與"测试二"相比要看網絡情況與記錄數多少,一般情況下BULK Insert方案總體快些。"测试二"則為標准SQL語法,比BULK Insert 或(Insert into + OpenRowSet方式)通用。
先將Txt文件轉爲Excel格式文件,然後將Excel導入數據庫。這樣不如直接導入TXT文本。
#14
"测试二"使用ADOComand遞交數據, 比使用DBX的TSQLConnection慢.
String SQL ;
TSQLConnection *SQLConn;
//---------------
DWORD StartAt=GetTickCount();
SQLConn->StartTransaction(TransactionDesc);
try{
for(int i = 0 ; i< 10*1000*1000; ++i) { //共提交10M次
SQL.Clear();
for(int i = 0 ; i < 10 ; ++i) //每次插入 10 行
SQL += "insert into TableA(Field0) Values('test data')\n";
SQLConnection->ExecuteDirect(SQL);
}
SQLConn->Commit(TransactionDesc);
}
catch(Exception &E){
SQLConn->Rollback(TransactionDesc);
throw Exception(E.Message);
}
catch(...){
SQLConn->Rollback(TransactionDesc);
throw Exception(String("unknow error"));
}
DWORD EndTime=GetTickCount();
ShowMessage((int)(EndTime-StartTime));
改用TSQLConnection ,使用 並將 iCacheSize= 10 ~ 100 ; 速度估計至少提升 10% .
String SQL ;
TSQLConnection *SQLConn;
//---------------
DWORD StartAt=GetTickCount();
SQLConn->StartTransaction(TransactionDesc);
try{
for(int i = 0 ; i< 10*1000*1000; ++i) { //共提交10M次
SQL.Clear();
for(int i = 0 ; i < 10 ; ++i) //每次插入 10 行
SQL += "insert into TableA(Field0) Values('test data')\n";
SQLConnection->ExecuteDirect(SQL);
}
SQLConn->Commit(TransactionDesc);
}
catch(Exception &E){
SQLConn->Rollback(TransactionDesc);
throw Exception(E.Message);
}
catch(...){
SQLConn->Rollback(TransactionDesc);
throw Exception(String("unknow error"));
}
DWORD EndTime=GetTickCount();
ShowMessage((int)(EndTime-StartTime));
改用TSQLConnection ,使用 並將 iCacheSize= 10 ~ 100 ; 速度估計至少提升 10% .
#15
先谢了 我先试试!!
#16
具体点
#17
用事务 估计慢
#18
MySQL有专门的读取语句,可以把文本文件中的数据读入数据库,比用insert快太多了
#19
需要获取数据,那是获取数据所消耗的时间,我所说的只是让数据库操作的时间尽可能少.
其实PPower说的使用DBX的TSQLConnection会比ADO操作快,这一点个人并不赞同.我没有做过实际的测试,所以无法下最终的结论.但是从理论上来讲,DBX也是需要通过ADO操作的,所以它的快只在于连接池的使用.对于单线程的程序来讲,可能在表面上看是会有所提升,但是这个并不能说明实质性的问题.
对于这种操作,个人建议是使用显示的事务,即强制每一批提交一个事务.对于支持事务的DBMS,并不会因为你没有显示使用事务,它就不会使用事务.只是这个事务是由DBMS自己去控制.
#20
MSSQL也有类似的,关键看源数据的格式等等.为什么你会觉得比使用insert快,只是因为很多细节由数据库系统内部进行控制和优化过了.类似的数据库系统,内部仍然还是一条条insert.
#21
如果是mssql,用bulk insert肯定是最快的,应该不会不行的啊,你试试建个文本文档到d盘下的0.txt,里面输入几行字符,然后执行:
BULK INSERT test from 'e:\0.txt' WITH (FIRSTROW=1,ROWTERMINATOR = '\n');
(test表只有一列varchar类型)
你那个提示找不到txt文件应该是路径没写对
BULK INSERT test from 'e:\0.txt' WITH (FIRSTROW=1,ROWTERMINATOR = '\n');
(test表只有一列varchar类型)
你那个提示找不到txt文件应该是路径没写对
#22
1.buld insert如果没有记错的话,文件需要在数据库的本地磁盘;
2.输出到文件也是需要消耗时间的.
#23
晕,又打错...
#24
To unsigned :
在使用事務的情況下,我的實測結果是DBX比ADO快不少。
沒測試過不用事務的情況。(DBX4 + MSSQL)
(測試時,第一次遞交數據因為服務器要擴張表空間,這時間太多因素影響,所以要忽略。每次測試前清空表再插入數據。)
以下是偽代碼:
StartTransaction
delete table
for(int i = 0 ; i < 10*1000*1000 ++i)
Execute(SQL,...);
Commit
同樣過程,DBX優於ADO即:
SQLConnection->ExecuteDirect(SQL);
優於
ADOConnection->Execute(SQL,
cmdTex,TExecuteOptions() << eoExecuteNoRecords); //可能是我選擇的參數不對。沒測試其他參數。
不清楚DBX4的MSSQL驅動是什麼方式與MSSQL交互的?
在使用事務的情況下,我的實測結果是DBX比ADO快不少。
沒測試過不用事務的情況。(DBX4 + MSSQL)
(測試時,第一次遞交數據因為服務器要擴張表空間,這時間太多因素影響,所以要忽略。每次測試前清空表再插入數據。)
以下是偽代碼:
StartTransaction
delete table
for(int i = 0 ; i < 10*1000*1000 ++i)
Execute(SQL,...);
Commit
同樣過程,DBX優於ADO即:
SQLConnection->ExecuteDirect(SQL);
優於
ADOConnection->Execute(SQL,
cmdTex,TExecuteOptions() << eoExecuteNoRecords); //可能是我選擇的參數不對。沒測試其他參數。
不清楚DBX4的MSSQL驅動是什麼方式與MSSQL交互的?
#25
呃...僵哥说的很详细恶劣
#26
对 用 buld insert 只有在本地磁盘 上可以操作
关键是 要解决 远程操作的问题 用的是 ms sql
#27
如果是远程共享的文件夹,用bulk insert并无问题,我已进行了测试,是可以的:
BULK INSERT test from '\\192.168.0.1\Share\0.txt' WITH (FIRSTROW=1,ROWTERMINATOR = '\n');
BULK INSERT test from '\\192.168.0.1\Share\0.txt' WITH (FIRSTROW=1,ROWTERMINATOR = '\n');
#28
不知道文本数据需要加工不?是不是规则的。
可以考虑如下方式:
给DTS包传递参数,支持的参数包括(环境变量、注册表值和参数字符)判断后,导入数据。用VBScript、JScript 编程,完成数据的判断和转换任务。
速度比较快。
可以考虑如下方式:
给DTS包传递参数,支持的参数包括(环境变量、注册表值和参数字符)判断后,导入数据。用VBScript、JScript 编程,完成数据的判断和转换任务。
速度比较快。
#29
见识
#30
谢谢该结贴了
#31
插入數據庫有個能提高效率的寫法
insert into table(field1,field2) values(value1, value2) values(value3,value4) values(value5,value6)....
現在程序裏把所有的value拼在一起 然後一起insert
這中間省去了很多時間 試一下看看
insert into table(field1,field2) values(value1, value2) values(value3,value4) values(value5,value6)....
現在程序裏把所有的value拼在一起 然後一起insert
這中間省去了很多時間 試一下看看
#32
更正 以上方法 在Sql Server中似乎不能跑
在mySql裏是可以這樣寫的 把多句合併成一句
insert into table(field) values(value1)
insert into table(field) values(value2)
insert into table(field) values(value3)
insert into table(field) values(value4)
insert into table(field) values(value5)
合併成
insert into table(field) values(value1),(value2),(value3),(value4),(value5)
在mySql裏是可以這樣寫的 把多句合併成一句
insert into table(field) values(value1)
insert into table(field) values(value2)
insert into table(field) values(value3)
insert into table(field) values(value4)
insert into table(field) values(value5)
合併成
insert into table(field) values(value1),(value2),(value3),(value4),(value5)