c++ - Sqlite C++ 插入很慢

标签 c++ sqlite

我有以下代码可以在 Sqlite 数据库中插入数据,但速度太慢。 Sqlite FAQ 说它一次可以支持 50K 的插入。我附上了以下代码。

SqliteBuffer.h

#ifndef SQLITE_BUFFER_H
#define SQLITE_BUFFER_H
#include "sqlite3.h"
#include <iostream>
class SqliteBuffer
{
    std::string db_name_;
    sqlite3 *db_;
    sqlite3_stmt *insert_stmt_;
    bool has_transaction_begun;
public:
    SqliteBuffer(std::string db_name);
    ~SqliteBuffer();
    int CreateTable();
    void SaveMessage(std::string msg);
    void BeginTransaction();
    void EndTransaction();
};
#endif

SqliteBuffer.cc

#include "SqliteBuffer.h"

int SqliteBuffer::CreateTable()
{
    sqlite3_stmt *create = NULL;
    if(sqlite3_prepare_v2(db_,"CREATE TABLE mytable (sif INTEGER PRIMARY KEY, log VARCHAR);",-1,&create,NULL)==SQLITE_OK){
        sqlite3_step(create);
        sqlite3_finalize(create);
    }
    return 0;
}
SqliteBuffer::SqliteBuffer(std::string db_name)
{
    int rc = sqlite3_open_v2(db_name.c_str(), &db_, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, NULL);
    if(rc!=SQLITE_OK){
        sqlite3_close_v2(db_);
    }
    CreateTable();
    rc = sqlite3_prepare_v2(db_,  "INSERT INTO mytable(log) VALUES (@LOG)", -1, &insert_stmt_, NULL);
}
void SqliteBuffer::SaveMessage(std::string message)
{
    BeginTransaction();
    sqlite3_bind_text(insert_stmt_,1,message.c_str(),-1,SQLITE_TRANSIENT);
    sqlite3_step(insert_stmt_);
    sqlite3_clear_bindings(insert_stmt_);
    sqlite3_reset(insert_stmt_);
}
void SqliteBuffer::BeginTransaction()
{
    if(has_transaction_begun == false){
        has_transaction_begun = true;
        sqlite3_exec(db_, "BEGIN TRANSACTION;",NULL,NULL,NULL);
    }
}
void SqliteBuffer::EndTransaction()
{
    if(has_transaction_begun == true){
        has_transaction_begun = false;
        sqlite3_exec(db_, "END TRANSACTION;",NULL,NULL,NULL);
    }
}

main.cc

#include "SqliteBuffer.h"

int main()
{
    SqliteBuffer *sql = new SqliteBuffer("E:\\asdf.db");
    for(int i(0); i<2000; i++){
        sql->SaveMessage("HELLO WORLD");
    }
    return 0;
}

我已经在 Visual Studio 10 中测试了这些代码,它们可以工作,但插入速度很慢。我在这里遗漏了什么吗?

最佳答案

除非您在一个事务中执行这些操作,否则每个查询都隐式地发生在它自己的事务中。对于 INSERT 操作,这需要至少两个刷新+同步操作:一个将数据写入日志(回滚或 WAL),一个将数据写入数据库本身,可能还有一个取决于期刊类型。对文件的同步操作非常慢,因为它们需要操作系统清空文件的写入缓冲区并等待磁盘报告数据已写入。

尝试在循环之前启动事务并在循环之后立即提交。您应该会看到显着的性能提升。这种技术的缺点是循环中间的应用程序或系统崩溃将导致所有未决更改回滚。

关于c++ - Sqlite C++ 插入很慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26974203/

相关文章:

java - 使用内存数据库(例如 SQLite)是否比将所有内容保存在 HashMap 或其他数据结构中更好?

java - SQLite连接池

c++ - 如何在 Qt 中创建 SQLite 数据库

Visual C++ 中的 C++ 代码库打开错误

c++ - CString 值在 64 位转换期间被截断

c++ - LNK2019 未解析的外部符号 NtOpenFile

c++ - to_string 不是 std 的成员,g++ (mingw) 说

C++ 模板黑魔法

sqlite select max查询和排序

android - 原始查询 : bind or column index out of range