使用sqlite3_exec 插入100万行数据需要 27 s,而使用sqlite3_bind_double 插入100万行数据只需要3.7 s。
主要是因为采用sqlite3_exec(),相当于每插入一行数据同时用到sqlite3_prepare_v2(),sqlite3_step() 和sqlite3_finalize(),另外需要把double 强制转换成 string 然后再转换成 const char*,这也需要耗费时间;而如果采用sqlite3_bind_double来加入数据,只要用到sqlite3_prepare_v2(),然后不断地使用sqlite3_step() 和 sqlite3_reset();并且不需要数据类型的转换。
当然,BEGIN TRANSACTION 的功能居功至伟。如果把sqlite3_exec(database,"BEGIN TRANSACTION;",NULL,&errmsg); 和sqlite3_exec(database,"COMMIT TRANSACTION;",NULL); 这两行注释掉,那么上述两种方法将耗费大量的时间;需要几分钟吧?
关于不同插入方法对插入速度的影响,见http://www.sqlite.org/faq.html#q19 中的“(19) INSERT is really slow - I can only do few dozen INSERTs per second”
下面是两种类型的代码:
使用sqlite3_exec 插入100万行数据
- #include<iostream>@H_404_39@
- #include<iostream>@H_404_39@
- #include"sqlite3.h"@H_404_39@
- #include<string.h>@H_404_39@
- #include<stdio.h>@H_404_39@
- #include<sys/time.h>@H_404_39@
- #include<boost/lexical_cast.hpp>@H_404_39@
- @H_404_39@
- @H_404_39@
- usingnamespacestd;@H_404_39@
- usingnamespaceboost;@H_404_39@
- @H_404_39@
- intfirst_row;@H_404_39@
- sqlite3*database;@H_404_39@
- @H_404_39@
- //callbackfunction;@H_404_39@
- intselect_callback(void*p_data,intnum_fields,char**p_fields,char**p_col_names)@H_404_39@
- {@H_404_39@
- inti;@H_404_39@
- int*nof_records=(int*)p_data;@H_404_39@
- (*nof_records)++;@H_404_39@
- @H_404_39@
- //first_rowwasdefinedin<select_stmt>function;@H_404_39@
- //iffirst_row==1,printthefirstrow@H_404_39@
- //andthensetfirst_row=0toavoidthesubsequentexecutionforthefollowingrows.@H_404_39@
- if(first_row==1)@H_404_39@
- {@H_404_39@
- first_row=0;@H_404_39@
- for(i=0;i<num_fields;i++)@H_404_39@
- {@H_404_39@
- //printf("%20s",p_col_names[i]);@H_404_39@
- }@H_404_39@
- //printf("\n");@H_404_39@
- for(i=0;i<num_fields*10;i++)@H_404_39@
- {@H_404_39@
- //printf("=");@H_404_39@
- }@H_404_39@
- //printf("\n");@H_404_39@
- }@H_404_39@
- @H_404_39@
- for(i=0;i<num_fields;i++)@H_404_39@
- {if(p_fields[i])@H_404_39@
- {@H_404_39@
- //printf("%20s",p_fields[i]);@H_404_39@
- }@H_404_39@
- else@H_404_39@
- {@H_404_39@
- //printf("%20s","");@H_404_39@
- }@H_404_39@
- }@H_404_39@
- @H_404_39@
- //printf("\n");@H_404_39@
- return0;@H_404_39@
- }@H_404_39@
- @H_404_39@
- @H_404_39@
- //Withcallbackfunction;@H_404_39@
- voidselect_stmt(constchar*stmt)@H_404_39@
- {char*errmsg;@H_404_39@
- intret;@H_404_39@
- intnrecs=0;@H_404_39@
- first_row=1;@H_404_39@
- @H_404_39@
- ret=sqlite3_exec(database,stmt,select_callback,&nrecs,&errmsg);@H_404_39@
- @H_404_39@
- if(ret!=sqlITE_OK)@H_404_39@
- {printf("Errorinselectstatement%s[%s].\n",errmsg);@H_404_39@
- }@H_404_39@
- else@H_404_39@
- {printf("\n%drecordsreturned.\n",nrecs);@H_404_39@
- }@H_404_39@
- }@H_404_39@
- @H_404_39@
- @H_404_39@
- //timecaculation@H_404_39@
- longtimecacul(){@H_404_39@
- structtimevaltv;@H_404_39@
- structtimezonetz;@H_404_39@
- gettimeofday(&tv,&tz);@H_404_39@
- return(tv.tv_sec*1000+tv.tv_usec/1000);@H_404_39@
- }@H_404_39@
- @H_404_39@
- intmain()@H_404_39@
- {longstarttime,endtime,resulttime;@H_404_39@
- @H_404_39@
- @H_404_39@
- @H_404_39@
- @H_404_39@
- char*errmsg;@H_404_39@
- sqlite3_open("./Database.db",&database);@H_404_39@
- @H_404_39@
- //sqlite3_exec(database,"PRAGMAsynchronous=OFF",&errmsg);@H_404_39@
- @H_404_39@
- @H_404_39@
- sqlite3_stmt*stmt;@H_404_39@
- strings="createtablewujie(xdecimal(5,2),ydecimal(5,zdecimal(5,2))";@H_404_39@
- constchar*creatTable=s.c_str();@H_404_39@
- cout<<"creatTable:"<<creatTable<<endl;@H_404_39@
- @H_404_39@
- //charcreatTable[]="createtablewujie(a,b,c)";@H_404_39@
- @H_404_39@
- @H_404_39@
- intresult=sqlite3_exec(database,@H_404_39@
- creatTable,//stmt@H_404_39@
- 0,@H_404_39@
- 0,@H_404_39@
- &errmsg@H_404_39@
- );@H_404_39@
- if(result!=sqlITE_OK)@H_404_39@
- {cout<<"\nCouldnotpreparestatement:creatTable:"<<result<<endl;@H_404_39@
- return1;@H_404_39@
- }@H_404_39@
- @H_404_39@
- @H_404_39@
- ////////BEGINTRANSACTION@H_404_39@
- starttime=timecacul();@H_404_39@
- sqlite3_exec(database,"BEGINTRANSACTION;",&errmsg);@H_404_39@
- @H_404_39@
- @H_404_39@
- stringinsertDataStr;@H_404_39@
- doublex,y,z;@H_404_39@
- doubleyTimes=1.222222222;@H_404_39@
- intiNum;@H_404_39@
- for(iNum=1;iNum<=1000000;iNum++)@H_404_39@
- {x=1*iNum;@H_404_39@
- y=yTimes*iNum;@H_404_39@
- z=2*iNum;@H_404_39@
- insertDataStr="insertintowujieVALUES("@H_404_39@
- +lexical_cast<string>(x)+","@H_404_39@
- +lexical_cast<string>(y)+","@H_404_39@
- +lexical_cast<string>(z)+")";@H_404_39@
- //cout<<"insertDataStr:"<<insertDataStr<<endl;@H_404_39@
- constchar*insertDataChar=insertDataStr.c_str();@H_404_39@
- @H_404_39@
- result=sqlite3_exec@H_404_39@
- (database,@H_404_39@
- insertDataChar,//stmt@H_404_39@
- 0,@H_404_39@
- 0,@H_404_39@
- &errmsg@H_404_39@
- );@H_404_39@
- @H_404_39@
- if(result!=sqlITE_OK)@H_404_39@
- {cout<<"\nCouldnotpreparestatement:inserData:"<<result<<endl;@H_404_39@
- return1;@H_404_39@
- }@H_404_39@
- }@H_404_39@
- @H_404_39@
- sqlite3_exec(database,"COMMITTRANSACTION;",NULL);@H_404_39@
- endtime=timecacul();@H_404_39@
- resulttime=endtime-starttime;@H_404_39@
- @H_404_39@
- printf("NOAUTOCOMMITINSERT:%dms.",resulttime);@H_404_39@
- cout<<endl;@H_404_39@
- @H_404_39@
- @H_404_39@
- charselectData[]="Selectx,zfromwujie";@H_404_39@
- starttime=timecacul();@H_404_39@
- select_stmt(selectData);@H_404_39@
- endtime=timecacul();@H_404_39@
- resulttime=endtime-starttime;@H_404_39@
- printf("Selectsqltime:%dms.",resulttime);@H_404_39@
- @H_404_39@
- sqlite3_close(database);@H_404_39@
- @H_404_39@
- return0;@H_404_39@
- }@H_404_39@
使用sqlite3_bind_double 插入100万行数据
- #include<iostream>@H_404_39@
- #include<iostream>@H_404_39@
- #include"sqlite3.h"@H_404_39@
- #include<string.h>@H_404_39@
- #include<stdio.h>@H_404_39@
- #include<sys/time.h>@H_404_39@
- #include<boost/lexical_cast.hpp>@H_404_39@
- @H_404_39@
- @H_404_39@
- usingnamespacestd;@H_404_39@
- usingnamespaceboost;@H_404_39@
- @H_404_39@
- intfirst_row;@H_404_39@
- sqlite3*database;@H_404_39@
- @H_404_39@
- //callbackfunction;@H_404_39@
- intselect_callback(void*p_data,intnum_fields,char**p_fields,char**p_col_names)@H_404_39@
- {@H_404_39@
- inti;@H_404_39@
- int*nof_records=(int*)p_data;@H_404_39@
- (*nof_records)++;@H_404_39@
- @H_404_39@
- //first_rowwasdefinedin<select_stmt>function;@H_404_39@
- //iffirst_row==1,printthefirstrow@H_404_39@
- //andthensetfirst_row=0toavoidthesubsequentexecutionforthefollowingrows.@H_404_39@
- if(first_row==1)@H_404_39@
- {@H_404_39@
- first_row=0;@H_404_39@
- for(i=0;i<num_fields;i++)@H_404_39@
- {@H_404_39@
- //printf("%20s",p_col_names[i]);@H_404_39@
- }@H_404_39@
- printf("\n");@H_404_39@
- for(i=0;i<num_fields*10;i++)@H_404_39@
- {@H_404_39@
- //printf("=");@H_404_39@
- }@H_404_39@
- //printf("\n");@H_404_39@
- }@H_404_39@
- @H_404_39@
- for(i=0;i<num_fields;i++)@H_404_39@
- {if(p_fields[i])@H_404_39@
- {@H_404_39@
- //printf("%20s",p_fields[i]);@H_404_39@
- }@H_404_39@
- else@H_404_39@
- {@H_404_39@
- //printf("%20s","");@H_404_39@
- }@H_404_39@
- }@H_404_39@
- @H_404_39@
- //printf("\n");@H_404_39@
- return0;@H_404_39@
- }@H_404_39@
- @H_404_39@
- //Withcallbackfunction;@H_404_39@
- voidselect_stmt(constchar*stmt)@H_404_39@
- {char*errmsg;@H_404_39@
- intret;@H_404_39@
- intnrecs=0;@H_404_39@
- first_row=1;@H_404_39@
- ret=sqlite3_exec(database,&errmsg);@H_404_39@
- @H_404_39@
- if(ret!=sqlITE_OK)@H_404_39@
- {printf("Errorinselectstatement%s[%s].\n",errmsg);@H_404_39@
- }@H_404_39@
- else@H_404_39@
- {printf("\n%drecordsreturned.\n",nrecs);@H_404_39@
- }@H_404_39@
- }@H_404_39@
- @H_404_39@
- @H_404_39@
- //timecaculation@H_404_39@
- longtimecacul(){@H_404_39@
- structtimevaltv;@H_404_39@
- structtimezonetz;@H_404_39@
- gettimeofday(&tv,&tz);@H_404_39@
- return(tv.tv_sec*1000+tv.tv_usec/1000);@H_404_39@
- }@H_404_39@
- @H_404_39@
- @H_404_39@
- intmain()@H_404_39@
- {longstarttime,resulttime;@H_404_39@
- @H_404_39@
- char*errmsg;@H_404_39@
- sqlite3_open("./Database.db",&database);@H_404_39@
- @H_404_39@
- sqlite3_stmt*stmt;@H_404_39@
- @H_404_39@
- strings="createtablewujie(x,z)";@H_404_39@
- constchar*creatTable=s.c_str();@H_404_39@
- //cout<<"creatTable:"<<creatTable<<endl;@H_404_39@
- @H_404_39@
- intresult=sqlite3_exec(database,@H_404_39@
- creatTable,//stmt@H_404_39@
- 0,@H_404_39@
- &errmsg@H_404_39@
- );@H_404_39@
- if(result!=sqlITE_OK)@H_404_39@
- {cout<<"\nCouldnotpreparestatement:creatTable:"<<result<<endl;@H_404_39@
- return1;@H_404_39@
- }@H_404_39@
- @H_404_39@
- @H_404_39@
- if(sqlite3_prepare@H_404_39@
- (database,@H_404_39@
- "insertintowujievalues(:x,:y,:z)",//stmt@H_404_39@
- -1,//Ifthanzero,thenstmtisreaduptothefirstnulterminator@H_404_39@
- &stmt,@H_404_39@
- 0//Pointertounusedportionofstmt@H_404_39@
- )@H_404_39@
- !=sqlITE_OK)@H_404_39@
- {printf("\nCouldnotpreparestatement.");@H_404_39@
- return1;@H_404_39@
- }@H_404_39@
- @H_404_39@
- intindex1,index2,index3;@H_404_39@
- index1=sqlite3_bind_parameter_index(stmt,":x");@H_404_39@
- index2=sqlite3_bind_parameter_index(stmt,":y");@H_404_39@
- index3=sqlite3_bind_parameter_index(stmt,":z");@H_404_39@
- @H_404_39@
- //cout<<index1<<endl;@H_404_39@
- //cout<<index2<<endl;@H_404_39@
- //cout<<index3<<endl;@H_404_39@
- @H_404_39@
- printf("\nThestatementhas%dwildcards\n",sqlite3_bind_parameter_count(stmt));@H_404_39@
- @H_404_39@
- @H_404_39@
- starttime=timecacul();@H_404_39@
- sqlite3_exec(database,"BEGINTRANSACTION;",&errmsg);@H_404_39@
- doublex,z;@H_404_39@
- doubleyTimes=1.222222222;@H_404_39@
- intiNum;@H_404_39@
- for(iNum=1;iNum<=1000000;iNum++)@H_404_39@
- {x=1*iNum;@H_404_39@
- y=yTimes*iNum;@H_404_39@
- z=2*iNum;@H_404_39@
- @H_404_39@
- if(sqlite3_bind_double(stmt,@H_404_39@
- index1,//Indexofwildcard@H_404_39@
- x@H_404_39@
- )@H_404_39@
- !=sqlITE_OK)@H_404_39@
- {printf("\nCouldnotbinddouble.\n");@H_404_39@
- return1;@H_404_39@
- }@H_404_39@
- @H_404_39@
- if(sqlite3_bind_double(stmt,@H_404_39@
- index2,//Indexofwildcard@H_404_39@
- y@H_404_39@
- )@H_404_39@
- !=sqlITE_OK)@H_404_39@
- {printf("\nCouldnotbinddouble.\n");@H_404_39@
- return1;@H_404_39@
- }@H_404_39@
- @H_404_39@
- if(sqlite3_bind_double(stmt,@H_404_39@
- index3,//Indexofwildcard@H_404_39@
- z@H_404_39@
- )@H_404_39@
- !=sqlITE_OK)@H_404_39@
- {printf("\nCouldnotbinddouble.\n");@H_404_39@
- return1;@H_404_39@
- }@H_404_39@
- @H_404_39@
- if(sqlite3_step(stmt)!=sqlITE_DONE)@H_404_39@
- {printf("\nCouldnotstep(execute)stmt.\n");@H_404_39@
- return1;@H_404_39@
- }@H_404_39@
- sqlite3_reset(stmt);@H_404_39@
- @H_404_39@
- }@H_404_39@
- @H_404_39@
- sqlite3_exec(database,"COMMITTRANSACTION;",NULL);@H_404_39@
- endtime=timecacul();@H_404_39@
- resulttime=endtime-starttime;@H_404_39@
- printf("NOAUTOCOMMITINSERT:%dms.",resulttime);@H_404_39@
- @H_404_39@
- ///////////////////////////////////////////////@H_404_39@
- starttime=timecacul();@H_404_39@
- @H_404_39@
- charselectData[]="Select*fromwujie";@H_404_39@
- select_stmt(selectData);@H_404_39@
- sqlite3_close(database);@H_404_39@
- @H_404_39@
- endtime=timecacul();@H_404_39@
- resulttime=endtime-starttime;@H_404_39@
- printf("NOAUTOCOMMITINSERT:%dms.",resulttime);@H_404_39@
- @H_404_39@
- return0;@H_404_39@
- } @H_404_39@