SQLite批量INSERT

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毫秒)!

在Python中使用SQLite进行批量插入数据可以通过以下步骤实现: 1. 首先,确保已经安装了Python的SQLite模块,可以使用`pip install sqlite3`命令进行安装。 2. 导入SQLite模块:`import sqlite3` 3. 连接到SQLite数据库:`conn = sqlite3.connect('database.db')`,其中'database.db'是数据库文件的名称,如果不存在则会创建一个新的数据库文件。 4. 创建一个游标对象:`cursor = conn.cursor()` 5. 定义插入数据的SQL语句:`sql = "INSERT INTO table_name (column1, column2, ...) VALUES (?, ?, ...)"`,其中table_name是表名,column1、column2等是表的列名。 6. 准备要插入的数据,以列表的形式存储:`data = [(value1, value2, ...), (value1, value2, ...), ...]` 7. 执行批量插入操作:`cursor.executemany(sql, data)` 8. 提交事务:`conn.commit()` 9. 关闭游标和数据库连接:`cursor.close()`和`conn.close()` 下面是一个示例代码: ```python import sqlite3 # 连接到SQLite数据库 conn = sqlite3.connect('database.db') cursor = conn.cursor() # 定义插入数据的SQL语句 sql = "INSERT INTO students (name, age) VALUES (?, ?)" # 准备要插入的数据 data = [('Alice', 20), ('Bob', 22), ('Charlie', 21)] # 执行批量插入操作 cursor.executemany(sql, data) # 提交事务 conn.commit() # 关闭游标和数据库连接 cursor.close() conn.close() ``` 请注意,上述示例中的表名为`students`,列名为`name`和`age`,你需要根据自己的数据库表结构进行相应的修改。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值