使用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,NULL,&errmsg); 和 sqlite3_exec(database,"COMMIT TRANSACTION;",NULL,NULL,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>
#include <iostream>
#include "sqlite3.h"
#include <string.h>
#include <stdio.h>
#include <sys/time.h>
#include <boost/lexical_cast.hpp>
using namespace std;
using namespace boost;
int first_row;
sqlite3* database;
// callback function;
int select_callback(void *p_data, int num_fields, char **p_fields, char **p_col_names)
{
int i;
int* nof_records = (int*) p_data;
(*nof_records)++;
// first_row was defined in <select_stmt> function;
// if first_row == 1, print the first row
// and then set first_row = 0 to avoid the subsequent execution for the following rows.
if (first_row == 1)
{
first_row = 0;
for (i=0; i < num_fields; i++)
{
// printf("%20s", p_col_names[i]);
}
// printf("\n");
for (i=0; i< num_fields*10; i++)
{
// printf("=");
}
// printf("\n");
}
for(i=0; i < num_fields; i++)
{ if (p_fields[i])
{
// printf("%20s", p_fields[i]);
}
else
{
// printf("%20s", " ");
}
}
// printf("\n");
return 0;
}
// With ca

通过对比测试发现,使用sqlite3_exec插入100万行数据耗时27秒,而使用sqlite3_bind_double仅需3.7秒。sqlite3_exec涉及到多次数据库操作和数据类型转换,而sqlite3_bind_double操作更高效。BEGIN TRANSACTION的使用对提升插入速度至关重要,无事务处理时,插入速度显著下降。更多详情可参考SQLite官方FAQ。
最低0.47元/天 解锁文章
6664

被折叠的 条评论
为什么被折叠?



