SQLite 插入大量数据慢的解决方法

本文探讨了SQLite数据库在进行大量数据插入时速度缓慢的问题,并提供了解决方案。通过使用显式事务处理,可以显著提高数据插入的速度,从而大幅提升SQLite的性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  sqlite 插入数据很慢的原因:sqlite在没有显式使用事务的时候会为每条insert都使用事务操作,而sqlite数据库是以文件的形式存在磁盘中,就相当于每次访问时都要打开一次文件,如果对数据进行大量的操作,时间都耗费在I/O操作上,所以很慢。

  解决方法是显式使用事务的形式提交:因为我们开始事务后,进行的大量操作的语句都保存在内存中,当提交时才全部写入数据库,此时,数据库文件也就只用打开一次。

  我在没有显式使用事务形式插入100条数据时用了12.226s;用显式事务形式,插入100条只用了0.172s,插入1000000条也才34.891s,相关很大吧。

  显式使用事务的例子:

  include

  include

  using namespace std;

  include sqlite/sqlite3.h

  int main()

  {

  sqlite3* db;

  int nResult = sqlite3_open(test.db,db);

  if (nResult != SQLITE_OK)

  {

  cout打开数据库失败:sqlite3_errmsg(db)endl; p=

  return 0;

  }

  else

  {

  cout数据库打开成功endl; p=

  }

  char* errmsg;

  nResult = sqlite3_exec(db,create table fuck(id integer primary key autoincrement,name varchar(100)),NULL,NULL,errmsg);

  if (nResult != SQLITE_OK)

  {

  sqlite3_close(db);

  couterrmsg; p=

  sqlite3_free(errmsg);

  return 0;

  }

  string strSql;

  strSql+=begin;\n;

  for (int i=0;i100;i++)

  {

  strSql+=insert into fuck values(null,'heh');\n;

  }

  strSql+=commit;;

  //coutstrsqlendl; p=

  SYSTEMTIME tm_s;

  GetLocalTime(tm_s);

  nResult = sqlite3_exec(db,strSql.c_str(),NULL,NULL,errmsg);

  SYSTEMTIME tm_e;

  GetLocalTime(tm_e);

  if (nResult != SQLITE_OK)

  {

  sqlite3_close(db);

  couterrmsgendl; p=

  sqlite3_free(errmsg);

  return 0;

  }

  coutstart:tm_s.wminute:tm_s.wsecond:tm_s.wmillisecondsendl; p=

  coutend :tm_e.wminute:tm_e.wsecond:tm_e.wmillisecondsendl; p=

  return 0;

### SQLite 插入数据性能优化原因分析 SQLite 插入数据速度的主要原因包括数据库默认配置、事务处理机制以及 SQL 语句的执行方式。在默认情况下,SQLite 的写同步(synchronous)设置为 `FULL`,这会确保每次事务提交都会将数据写入磁盘,从而保证数据完整性,但这也显著降低了插入速度[^2]。 此外,使用 `sqlite3_exec()` 函数直接执行包含 SQL 语句的字符串会导致每次插入操作都需要进行“词法分析”和“语法分析”,即使开启了事务也无法避免这一开销。这种重复解析过程对于大量数据插入来说是极大的性能瓶颈。 为了进一步提升性能,可以采用“执行准备”机制,即先将 SQL 语句编译好,然后通过绑定参数的方式逐条执行。这种方式减少了重复解析 SQL 语句的开销,提高了插入效率。 另一个影响插入性能的关键因素是事务的使用。如果每条插入语句都单独作为一个事务提交,则每次都要经历日志写入、页刷盘等操作,导致性能下降。相反,将多个插入操作包裹在一个事务中,可以显著减少磁盘 I/O 操作次数,从而提高整体性能[^4]。 此外,构建长 SQL 字符串并一次性执行多条插入语句的方式虽然也能提升效率,但在实际测试中发现,某些场景下插入一条数据仍可能需要近 50ms,这对于用户体验而言仍然较差。因此,合理的批量处理策略与事务控制是关键[^3]。 以下是一个优化示例,展示了如何通过预编译语句和事务机制来提升插入性能: ```c sqlite3_exec(db, "BEGIN TRANSACTION", 0, 0, 0); const char* sql = "INSERT INTO table (col1, col2) VALUES (?, ?)"; sqlite3_stmt* stmt; sqlite3_prepare_v2(db, sql, -1, &stmt, 0); for (int i = 0; i < count; ++i) { sqlite3_bind_text(stmt, 1, data[i].col1, -1, SQLITE_STATIC); sqlite3_bind_int(stmt, 2, data[i].col2); sqlite3_step(stmt); sqlite3_reset(stmt); } sqlite3_finalize(stmt); sqlite3_exec(db, "COMMIT TRANSACTION", 0, 0, 0); ``` 该方法不仅减少了 SQL 解析次数,还利用了事务机制,大幅提升了插入效率[^2]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值