网站首页 > 文章精选 正文
SQLite是一种轻量级、零配置的数据库管理系统。它的数据存储在一个单一的磁盘文件上,使得它非常适合嵌入式系统和移动应用。
在SQLite数据库中进行大批量记录INSERT,有三种方法,三种方法的效率由高低,本文举例说明。
方法一:逐条记录INSERT,这也是效率最低的方法
下面以逐条记录INSERT的方法,向SQLite数据库插入1000条数据,看一下耗时多长。
预先创建数据库myDB.db,在其中创建表myTabel:
CREATE TABLE IF NOT EXISTS my_table ( \
id INTEGER PRIMARY KEY, \
a TEXT, \
b INTEGER)
其中,id字段为自增字段,INSERT时,只需要提供a和b的值即可,代码如下:
#include <chrono>
#include <iostream>
#include <thread>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
//方式一:单条记录逐条INSERT
auto tms = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock().now().time_since_epoch()).count();
for(int i = 0; i < 1000; i++)
{
int b = i + 1;
QString a = QString("a_%1").arg(b);
sql = QString("INSERT INTO myTable (a, b) VALUES('%1', %2)").arg(a).arg(b);
if(!query.exec(sql))
{
std::cout << "INSERT INTO failed" << std::endl;
db.close();
return 0;
}
}
auto tme = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock().now().time_since_epoch()).count();
int span = static_cast<int>(tme - tms);
std::cout << "方式一:插入1000条记录耗时 " << span << " 毫秒!" << std::endl;
//以上程序输出 方式一:插入1000条记录耗时 171978 毫秒!
以上可见,使用逐条记录INSERT的方法,插入1000条记录到SQLite数据库,需要耗时172秒(171987毫秒)!
方法二,使用 UNION ALL 的SQL语句批量INSERT,这个方法效率居中
”UNION ALL” 是一种用来合并两个或多个 SQL 查询结果集的操作符。与 “UNION” 不同的是,”UNION ALL” 不会去重查询结果集,而是将所有的行都包含在结果中。
SQLite中的代码生成器会使用一种递归算法来对复合SELECT语句进行处理。对栈的大小有必要进行一下限制,我们会因为这个缘故对复合SELECT中的段落数量进行限制。段落的最大数量限制参数就是
SQLITE_MAX_COMPOUND_SELECT ,其默认值为 500。
由于UNION ALL的记录数目最大被限制为500条,因此,以下代码中,将1000条记录分拆成500条的2个部分进行INSERT操作:
//方式二:1000条记录合并到一个INSERT语句插入
//SQLITE_MAX_COMPOUND_SELECT限制500条
auto tms = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock().now().time_since_epoch()).count();
QString sql = "INSERT INTO my_table(a, b) ";
for(int i = 0; i < 500; i++)
{
int b = i + 1;
QString a = QString("a_%1").arg(b);
sql += QString("SELECT '%1', %2 ").arg(a).arg(b);
if(i != 499)
sql += "UNION ALL ";
}
if(!query.exec(sql))
{
std::cout << "UNION 1 INSERT INTO failed : " << query.lastError().text().toStdString() << std::endl;
db.close();
return;
}
sql = "INSERT INTO my_table(a, b) ";
for(int i = 500; i < 1000; i++)
{
int b = i + 1;
QString a = QString("a_%1").arg(b);
sql += QString("SELECT '%1', %2 ").arg(a).arg(b);
if(i != 999)
sql += "UNION ALL ";
}
if(!query.exec(sql))
{
std::cout << "UNION 2 INSERT INTO failed : " << query.lastError().text().toStdString() << std::endl;
db.close();
return;
}
auto tme = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock().now().time_since_epoch()).count();
int span = static_cast<int>(tme - tms);
std::cout << "方式二:插入1000条记录耗时 " << span << " 毫秒!" << std::endl;
//以上程序输出 方式二:插入1000条记录耗时 310 毫秒!
以上可见,使用UNION ALL的SQL语句批量INSERT的方法,插入1000条记录到SQLite数据库,需要耗时0.31秒(310毫秒)!
方法三,开启事务,逐条记录INSERT,提交事务,这是效率最高的方法
在SQLite中,事务是一种机制,用于确保数据库操作的一致性和完整性。事务通过保证一系列操作的成功或失败不会影响数据库的状态来实现这一点。
以下代码通过启动事务,逐条插入,最后提交事务的方式将1000条记录插入SQLite数据库:
//方式三:启动事务,单条记录逐条INSERT,提交事务
auto tms = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock().now().time_since_epoch()).count();
//启动事务
db.transaction();
//逐条插入
for(int i = 0; i < 1000; i++)
{
int b = i + 1;
QString a = QString("a_%1").arg(b);
sql = QString("INSERT INTO my_table (a, b) VALUES('%1', %2)").arg(a).arg(b);
if(!query.exec(sql))
{
std::cout << "transaction INSERT INTO failed" << std::endl;
db.rollback();
db.close();
return;
}
}
//提交事务
db.commit();
auto tme = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock().now().time_since_epoch()).count();
int span = static_cast<int>(tme - tms);
std::cout << "方式三:插入1000条记录耗时 " << span << " 毫秒!" << std::endl;
//以上程序输出 方式三:插入1000条记录耗时 192 毫秒!
以上可见,使用通过启动事务,逐条插入,最后提交事务的方式,插入1000条记录到SQLite数据库,需要耗时0.192秒(192毫秒)!
猜你喜欢
- 2025-06-13 oracle sql优化(oracle sql优化面试技巧)
- 2025-06-13 全面掌握 LINQ:方法汇总与实用技巧
- 2025-06-13 最详细的 MySQL 执行计划和索引优化!
- 2025-06-13 Redis的集合(Set):不重复的才是最好的!抽奖、共同好友就用它
- 2025-06-13 程序员必知的10个SQL优化实用技巧,熟记后让你效率提升翻倍
- 2025-06-13 查询中,有没有可能多个索引一起用呢?
- 2025-06-13 修图app年度推荐 - iOS(修图软件iphone)
- 2025-06-13 微信生态账号体系-各ID介绍与Unionid的获取
- 2025-06-13 我试了试用 SQL查 Linux日志,好用到飞起
- 2025-06-13 Mysql性能优化这5点你知道吗?简单却容易被初学者忽略!
- 最近发表
- 标签列表
-
- newcoder (56)
- 字符串的长度是指 (45)
- drawcontours()参数说明 (60)
- unsignedshortint (59)
- postman并发请求 (47)
- python列表删除 (50)
- 左程云什么水平 (56)
- 计算机网络的拓扑结构是指() (45)
- 编程题 (64)
- postgresql默认端口 (66)
- 数据库的概念模型独立于 (48)
- 产生系统死锁的原因可能是由于 (51)
- 数据库中只存放视图的 (62)
- 在vi中退出不保存的命令是 (53)
- 哪个命令可以将普通用户转换成超级用户 (49)
- noscript标签的作用 (48)
- 联合利华网申 (49)
- swagger和postman (46)
- 结构化程序设计主要强调 (53)
- 172.1 (57)
- apipostwebsocket (47)
- 唯品会后台 (61)
- 简历助手 (56)
- offshow (61)
- mysql数据库面试题 (57)