Qt+sqlite3使用事务提升插入效率

参考:

【精选】SQLite批量插入效率_sqlite 批量插入_PengX_Seek的博客-CSDN博客

(1)不使用事务时:

cpp 复制代码
	clock_t t_start = clock();
	QSqlQuery query(db);
	QString sql("insert into test(col1,col2) values(1,2);");
	for (int i = 0; i < 1000; i++)
	{
		query.exec(sql);
		//qDebug() << query.lastError();
	}
	clock_t t_stop = clock();
	std::cout << "cost time " << (t_stop - t_start) << " ms" << std::endl;

cost time 22566 ms

每次使用SQL语句,都会打开和关闭数据库文件(共1000次)。

(2)使用事务时:

cpp 复制代码
	clock_t t_start = clock();

	QSqlQuery begin(db);
	begin.exec("begin;");
	QSqlQuery query(db);

	QString sql("insert into test(col1,col2) values(1,2);");
	for (int i = 0; i < 1000; i++)
	{
		query.exec(sql);
		//qDebug() << query.lastError();
	}
	QSqlQuery commit(db);
	commit.exec("commit;");
	//commit.exec("end;");
    //使用end;效果一样
	clock_t t_stop = clock();
	std::cout << "cost time " << (t_stop - t_start) << " ms" << std::endl;

cost time 67 ms

只打开和关闭了一次数据库文件。

(3)我想导入数据库3500万条数据。(Qt)

cpp 复制代码
	clock_t t_start = clock();
	//3500万
	for (int j = 0; j < 3500; j++)
	{
		QSqlQuery begin(db);
		begin.exec("begin;");
		QSqlQuery query(db);
		for (int i = 0; i < 10000; i++)
		{
			QString sql = QString("insert into test(col1,col2) values(%1,2);").arg(j*10000+i);
			query.exec(sql);
		}
		qDebug() << j;
		QSqlQuery commit(db);
		commit.exec("commit;");
	}
	//commit.exec("end;");
	clock_t t_stop = clock();
	std::cout << "cost time " << (t_stop - t_start) << " ms" << std::endl;

cost time 813590 ms

时间有点久。

之前尝试只begin,commit一次,但感觉效果不好(猜测可能是一次提交的数据太多了)。

(4)依然是导入3500万数据。(Qt---prepare)

参考这篇文章:

Qt 使用SQLite的性能优化的亿点点记录-云社区-华为云 (huaweicloud.com)

cpp 复制代码
	clock_t t_start = clock();
	//3500万
	for (int j = 0; j < 3500; j++)
	{
		QSqlQuery begin(db);
		begin.prepare("begin;");
		begin.exec();
		QSqlQuery query(db);
		for (int i = 0; i < 10000; i++)
		{
			query.prepare("insert into test(col1,col2) values(%1,2);");
			query.bindValue(":1", j * 10000 + i);
			query.exec();
		}
		qDebug() << j;
		QSqlQuery commit(db);
		commit.prepare("commit");
		commit.exec();
	}
	//commit.exec("end;");
	clock_t t_stop = clock();
	std::cout << "cost time " << (t_stop - t_start) << " ms" << std::endl;

cost time 951928 ms

速度也不快!

(5)依然导入3500万数据(C++,执行准备)

参考:

Sqlite3写性能优化-每秒百万条写入 - 陈小蓝 - 博客园 (cnblogs.com)

cpp 复制代码
	clock_t t_start = clock();
	sqlite3* db;
	char* zErrMsg = 0;
	int rc;
	rc = sqlite3_open("test.db", &db);
	if (rc) {
		fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
		exit(0);
	}
	else {
		fprintf(stderr, "Open database successfully\n");
	}
	sqlite3_exec(db, "CREATE TABLE Test(ID INTEGER,var0 INTEGER,var1 REAL,var2 TEXT);", 0, 0, 0);
	sqlite3_stmt* pPrepare = nullptr;
	auto sql = "INSERT INTO Test (ID,var0,var1,var2) VALUES (?,?,?,?);";
	sqlite3_prepare_v2(db, sql, strlen(sql), &pPrepare, 0);
	sqlite3_exec(db, "BEGIN", 0, 0, 0);
	const int maxcount = 3500*10000;
	for (int i = 0; i < maxcount; i++)
	{
		sqlite3_reset(pPrepare);
		sqlite3_bind_int(pPrepare, 1, 0);
		sqlite3_bind_int(pPrepare, 2, 1);
		sqlite3_bind_double(pPrepare, 3, 2.0);
		const char* str = "hello sqlite3";
		sqlite3_bind_text(pPrepare, 4, str, strlen(str), 0);
		sqlite3_step(pPrepare);
		int err = sqlite3_step(pPrepare);
		assert(SQLITE_DONE == err);
		if (i % 10000 == 9999)
		{
			qDebug() << i;
			sqlite3_exec(db, "COMMIT", 0, 0, 0);
			sqlite3_exec(db, "BEGIN", 0, 0, 0);
		}
	}
	sqlite3_exec(db, "COMMIT", 0, 0, 0);
	sqlite3_finalize(pPrepare);
	sqlite3_close(db);
	clock_t t_stop = clock();
	std::cout << "cost time " << (t_stop - t_start) << " ms" << std::endl;

cost time 198837 ms

3500*10000/(20*10000)=350/2=175

即175条数据/ms

感觉好像快了,但是因为表结构变化了,就不互相比较了。

相关环境的搭建(vs2019下引入sqlite3)参考:

主要是第二篇文章:

C/C++ SQLite3安装及使用 - _Return - 博客园 (cnblogs.com)

VS2019下Sqlite3数据库的环境搭建及简单应用_sqlite3_exec vs2019 csdn-CSDN博客

6.在其中加入这句:(c++,关闭写同步)

cpp 复制代码
sqlite3_exec(db, "PRAGMA synchronous = OFF", 0, 0, 0);

cost time 137753 ms

3500*10000/137753约为254

254条数据/ms

相关推荐
Web3&Basketball2 小时前
实测Gemini4Argon:ERQA 87%登顶长程任务榜
数据库·python·大模型·多模态·gemini·长上下文·推理优化
xiaogai_gai2 小时前
金蝶收料通知单查询策略实战教程:从源系统拉取到中间层落地的完整路径
java·前端·数据库
注塑机数据采集联网3 小时前
注塑机数据采集网关对接MES系统数字化技术方案
大数据·网络·数据库·物联网·数据挖掘·数据分析
像风一样自由20203 小时前
56.实战PostgreSQL-pgvector-FastAPI构建轻量级RAG
数据库·人工智能·postgresql·大模型·fastapi·智能体
User_芊芊君子4 小时前
KFS异构同步_260条链路DDL自动转换解析
数据库·ai·大模型
xiancai_xianyu4 小时前
Text2SQL落地生产库前,SQL要过哪三道闸
前端·数据库·sql·sql注入·text2sql·ai agent开发·企业级ai框架
Zucker n4 小时前
一款适合研究生科研工作安排的日历
linux·数据库·python
Sharewinfo_BJ5 小时前
Power BI沿袭视图详解:从看懂链路到做影响分析
数据库·数据分析·智信bi·上北智信
l1t5 小时前
DeepSeek总结的 DuckDB 2.0 中更简洁的变量语法
数据库·sql
sunshine8855 小时前
集成电路(IC)设计与封测行业10大常用ERP系统分析
大数据·数据库·人工智能