对比sqlite3_exec 和sqlite3_bind 插入100万行数据的速度 with BEGIN TRANSACTION using C++ and SQLite

前端之家收集整理的这篇文章主要介绍了对比sqlite3_exec 和sqlite3_bind 插入100万行数据的速度 with BEGIN TRANSACTION using C++ and SQLite前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

使用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万行数据

  1. #include<iostream>
  2. #include<iostream>
  3. #include"sqlite3.h"
  4. #include<string.h>
  5. #include<stdio.h>
  6. #include<sys/time.h>
  7. #include<boost/lexical_cast.hpp>
  8. usingnamespacestd;
  9. usingnamespaceboost;
  10. intfirst_row;
  11. sqlite3*database;
  12. @H_502_142@//callbackfunction;
  13. intselect_callback(void*p_data,intnum_fields,char**p_fields,char**p_col_names)
  14. {
  15. inti;
  16. int*nof_records=(int*)p_data;
  17. (*nof_records)++;
  18. @H_502_142@//first_rowwasdefinedin<select_stmt>function;
  19. @H_502_142@//iffirst_row==1,printthefirstrow
  20. @H_502_142@//andthensetfirst_row=0toavoidthesubsequentexecutionforthefollowingrows.
  21. if(first_row==1)
  22. {
  23. first_row=0;
  24. for(i=0;i<num_fields;i++)
  25. {
  26. @H_502_142@//printf("%20s",p_col_names[i]);
  27. }
  28. @H_502_142@//printf("\n");
  29. for(i=0;i<num_fields*10;i++)
  30. {
  31. @H_502_142@//printf("=");
  32. }
  33. @H_502_142@//printf("\n");
  34. }
  35. for(i=0;i<num_fields;i++)
  36. {if(p_fields[i])
  37. {
  38. @H_502_142@//printf("%20s",p_fields[i]);
  39. }
  40. else
  41. {
  42. @H_502_142@//printf("%20s","");
  43. }
  44. }
  45. @H_502_142@//printf("\n");
  46. return0;
  47. }
  48. @H_502_142@//Withcallbackfunction;
  49. voidselect_stmt(constchar*stmt)
  50. {char*errmsg;
  51. intret;
  52. intnrecs=0;
  53. first_row=1;
  54. ret=sqlite3_exec(database,stmt,select_callback,&nrecs,&errmsg);
  55. if(ret!=sqlITE_OK)
  56. {printf("Errorinselectstatement%s[%s].\n",errmsg);
  57. }
  58. else
  59. {printf("\n%drecordsreturned.\n",nrecs);
  60. }
  61. }
  62. @H_502_142@//timecaculation
  63. longtimecacul(){
  64. structtimevaltv;
  65. structtimezonetz;
  66. gettimeofday(&tv,&tz);
  67. return(tv.tv_sec*1000+tv.tv_usec/1000);
  68. }
  69. intmain()
  70. {longstarttime,endtime,resulttime;
  71. char*errmsg;
  72. sqlite3_open("./Database.db",&database);
  73. @H_502_142@//sqlite3_exec(database,"PRAGMAsynchronous=OFF",&errmsg);
  74. sqlite3_stmt*stmt;
  75. strings="createtablewujie(xdecimal(5,2),ydecimal(5,zdecimal(5,2))";
  76. constchar*creatTable=s.c_str();
  77. cout<<"creatTable:"<<creatTable<<endl;
  78. @H_502_142@//charcreatTable[]="createtablewujie(a,b,c)";
  79. intresult=sqlite3_exec(database,
  80. creatTable,@H_502_142@//stmt
  81. 0,
  82. 0,
  83. &errmsg
  84. );
  85. if(result!=sqlITE_OK)
  86. {cout<<"\nCouldnotpreparestatement:creatTable:"<<result<<endl;
  87. return1;
  88. }
  89. @H_502_142@////////BEGINTRANSACTION
  90. starttime=timecacul();
  91. sqlite3_exec(database,"BEGINTRANSACTION;",&errmsg);
  92. stringinsertDataStr;
  93. doublex,y,z;
  94. doubleyTimes=1.222222222;
  95. intiNum;
  96. for(iNum=1;iNum<=1000000;iNum++)
  97. {x=1*iNum;
  98. y=yTimes*iNum;
  99. z=2*iNum;
  100. insertDataStr="insertintowujieVALUES("
  101. +lexical_cast<string>(x)+","
  102. +lexical_cast<string>(y)+","
  103. +lexical_cast<string>(z)+")";
  104. @H_502_142@//cout<<"insertDataStr:"<<insertDataStr<<endl;
  105. constchar*insertDataChar=insertDataStr.c_str();
  106. result=sqlite3_exec
  107. (database,
  108. insertDataChar,@H_502_142@//stmt
  109. 0,
  110. 0,
  111. &errmsg
  112. );
  113. if(result!=sqlITE_OK)
  114. {cout<<"\nCouldnotpreparestatement:inserData:"<<result<<endl;
  115. return1;
  116. }
  117. }
  118. sqlite3_exec(database,"COMMITTRANSACTION;",NULL);
  119. endtime=timecacul();
  120. resulttime=endtime-starttime;
  121. printf("NOAUTOCOMMITINSERT:%dms.",resulttime);
  122. cout<<endl;
  123. charselectData[]="Selectx,zfromwujie";
  124. starttime=timecacul();
  125. select_stmt(selectData);
  126. endtime=timecacul();
  127. resulttime=endtime-starttime;
  128. printf("Selectsqltime:%dms.",resulttime);
  129. sqlite3_close(database);
  130. return0;
  131. }


使用sqlite3_bind_double 插入100万行数据

  1. #include<iostream>
  2. #include<iostream>
  3. #include"sqlite3.h"
  4. #include<string.h>
  5. #include<stdio.h>
  6. #include<sys/time.h>
  7. #include<boost/lexical_cast.hpp>
  8. usingnamespacestd;
  9. usingnamespaceboost;
  10. intfirst_row;
  11. sqlite3*database;
  12. //callbackfunction;
  13. intselect_callback(void*p_data,intnum_fields,char**p_fields,char**p_col_names)
  14. {
  15. inti;
  16. int*nof_records=(int*)p_data;
  17. (*nof_records)++;
  18. //first_rowwasdefinedin<select_stmt>function;
  19. //iffirst_row==1,printthefirstrow
  20. //andthensetfirst_row=0toavoidthesubsequentexecutionforthefollowingrows.
  21. if(first_row==1)
  22. {
  23. first_row=0;
  24. for(i=0;i<num_fields;i++)
  25. {
  26. //printf("%20s",p_col_names[i]);
  27. }
  28. printf("\n");
  29. for(i=0;i<num_fields*10;i++)
  30. {
  31. //printf("=");
  32. }
  33. //printf("\n");
  34. }
  35. for(i=0;i<num_fields;i++)
  36. {if(p_fields[i])
  37. {
  38. //printf("%20s",p_fields[i]);
  39. }
  40. else
  41. {
  42. //printf("%20s","");
  43. }
  44. }
  45. //printf("\n");
  46. return0;
  47. }
  48. //Withcallbackfunction;
  49. voidselect_stmt(constchar*stmt)
  50. {char*errmsg;
  51. intret;
  52. intnrecs=0;
  53. first_row=1;
  54. ret=sqlite3_exec(database,&errmsg);
  55. if(ret!=sqlITE_OK)
  56. {printf("Errorinselectstatement%s[%s].\n",errmsg);
  57. }
  58. else
  59. {printf("\n%drecordsreturned.\n",nrecs);
  60. }
  61. }
  62. //timecaculation
  63. longtimecacul(){
  64. structtimevaltv;
  65. structtimezonetz;
  66. gettimeofday(&tv,&tz);
  67. return(tv.tv_sec*1000+tv.tv_usec/1000);
  68. }
  69. intmain()
  70. {longstarttime,resulttime;
  71. char*errmsg;
  72. sqlite3_open("./Database.db",&database);
  73. sqlite3_stmt*stmt;
  74. strings="createtablewujie(x,z)";
  75. constchar*creatTable=s.c_str();
  76. //cout<<"creatTable:"<<creatTable<<endl;
  77. intresult=sqlite3_exec(database,
  78. creatTable,//stmt
  79. 0,
  80. &errmsg
  81. );
  82. if(result!=sqlITE_OK)
  83. {cout<<"\nCouldnotpreparestatement:creatTable:"<<result<<endl;
  84. return1;
  85. }
  86. if(sqlite3_prepare
  87. (database,
  88. "insertintowujievalues(:x,:y,:z)",//stmt
  89. -1,//Ifthanzero,thenstmtisreaduptothefirstnulterminator
  90. &stmt,
  91. 0//Pointertounusedportionofstmt
  92. )
  93. !=sqlITE_OK)
  94. {printf("\nCouldnotpreparestatement.");
  95. return1;
  96. }
  97. intindex1,index2,index3;
  98. index1=sqlite3_bind_parameter_index(stmt,":x");
  99. index2=sqlite3_bind_parameter_index(stmt,":y");
  100. index3=sqlite3_bind_parameter_index(stmt,":z");
  101. //cout<<index1<<endl;
  102. //cout<<index2<<endl;
  103. //cout<<index3<<endl;
  104. printf("\nThestatementhas%dwildcards\n",sqlite3_bind_parameter_count(stmt));
  105. starttime=timecacul();
  106. sqlite3_exec(database,"BEGINTRANSACTION;",&errmsg);
  107. doublex,z;
  108. doubleyTimes=1.222222222;
  109. intiNum;
  110. for(iNum=1;iNum<=1000000;iNum++)
  111. {x=1*iNum;
  112. y=yTimes*iNum;
  113. z=2*iNum;
  114. if(sqlite3_bind_double(stmt,
  115. index1,//Indexofwildcard
  116. x
  117. )
  118. !=sqlITE_OK)
  119. {printf("\nCouldnotbinddouble.\n");
  120. return1;
  121. }
  122. if(sqlite3_bind_double(stmt,
  123. index2,//Indexofwildcard
  124. y
  125. )
  126. !=sqlITE_OK)
  127. {printf("\nCouldnotbinddouble.\n");
  128. return1;
  129. }
  130. if(sqlite3_bind_double(stmt,
  131. index3,//Indexofwildcard
  132. z
  133. )
  134. !=sqlITE_OK)
  135. {printf("\nCouldnotbinddouble.\n");
  136. return1;
  137. }
  138. if(sqlite3_step(stmt)!=sqlITE_DONE)
  139. {printf("\nCouldnotstep(execute)stmt.\n");
  140. return1;
  141. }
  142. sqlite3_reset(stmt);
  143. }
  144. sqlite3_exec(database,"COMMITTRANSACTION;",NULL);
  145. endtime=timecacul();
  146. resulttime=endtime-starttime;
  147. printf("NOAUTOCOMMITINSERT:%dms.",resulttime);
  148. ///////////////////////////////////////////////
  149. starttime=timecacul();
  150. charselectData[]="Select*fromwujie";
  151. select_stmt(selectData);
  152. sqlite3_close(database);
  153. endtime=timecacul();
  154. resulttime=endtime-starttime;
  155. printf("NOAUTOCOMMITINSERT:%dms.",resulttime);
  156. return0;
  157. }
原文链接:https://www.f2er.com/sqlite/199866.html

猜你在找的Sqlite相关文章