在sqlite3更快的批量插入?

我有一个约30000行的数据,我想加载到sqlite3数据库的文件。 有没有比为每行数据生成插入语句更快的方法?

数据是空格分隔的,并直接映射到sqlite3表。 是否有任何种类的批量插入方法来添加卷数据到数据库?

有没有人devise了一些非常好的方法来做到这一点,如果它不是内置的?

我应该问这个问题,有没有一个C ++的方法来从API中做到这一点?

    你也可以尝试调整一些参数,以获得额外的速度。 具体来说,您可能需要PRAGMA synchronous = OFF;

    • 将所有INSERT包装在一个事务中,即使只有一个用户,也要快得多。
    • 使用准备的语句。

    你想使用.import命令。 例如:

     $ cat demotab.txt 44 92 35 94 43 94 195 49 66 28 135 93 135 91 67 84 135 94 $ echo "create table mytable (col1 int, col2 int);" | sqlite3 foo.sqlite $ echo ".import demotab.txt mytable" | sqlite3 foo.sqlite $ sqlite3 foo.sqlite -- Loading resources from /Users/ramanujan/.sqliterc SQLite version 3.6.6.2 Enter ".help" for instructions Enter SQL statements terminated with a ";" sqlite> select * from mytable; col1 col2 44 92 35 94 43 94 195 49 66 28 135 93 135 91 67 84 135 94 

    请注意,这个批量加载命令不是SQL,而是SQLite的自定义function。 因此,它有一个奇怪的语法,因为我们通过echo将它传递给交互式命令行解释器sqlite3

    在PostgreSQL中相当于COPY FROM : http : //www.postgresql.org/docs/8.1/static/sql-copy.html

    在MySQL中,它是LOAD DATA LOCAL INFILE : http : //dev.mysql.com/doc/refman/5.1/en/load-data.html

    最后一件事:记住谨慎使用.separator的价值。 在进行批量插入时,这是一个非常常见的问题。

     sqlite> .show .separator echo: off explain: off headers: on mode: list nullvalue: "" output: stdout separator: "\t" width: 

    在执行.import之前,您应该明确地将分隔符设置为空格,制表符或逗号。

    • PRAGMA default_cache_size增加到更大的数字。 这将增加caching在内存中的页面数量。

    • 将所有插入包装到单个事务中,而不是每行中的一个事务。

    • 使用编译的SQL语句来执行插入。
    • 最后,如前所述,如果您愿意放弃完整的ACID合规性,请将PRAGMA synchronous = OFF;

    RE:“是否有更快的方式为每行数据生成插入语句?

    第一:通过使用Sqlite3的虚拟表格API,例如,将其削减为2个SQL语句

     create virtual table vtYourDataset using yourModule; -- Bulk insert insert into yourTargetTable (x, y, z) select x, y, z from vtYourDataset; 

    这里的想法是,你实现了一个C接口,它读取你的源数据集,并把它作为一个虚拟表提供给SQlite,然后一次执行从源到目标表的SQL拷贝。 这听起来比实际上更难,我已经用这种方法来测量巨大的速度。

    第二:利用这里提供的其他build议,即杂注设置和使用交易。

    第三:也许看看你是否可以取消目标表上的一些索引。 这样sqlite将有更less的索引来更新插入的每一行

    没有办法批量插入,但有一种方法可以将大块写入内存,然后将它们提交到数据库。 对于C / C ++ API,只需要:

    sqlite3_exec(db,“BEGIN TRANSACTION”,NULL,NULL,NULL);

    …(INSERT语句)

    sqlite3_exec(db,“COMMIT TRANSACTION”,NULL,NULL,NULL);

    假设db是你的数据库指针。

    一个很好的折衷办法是将你的INSERTS包装在BEGIN之间; 和END; 关键字即:

     BEGIN; INSERT INTO table VALUES (); INSERT INTO table VALUES (); ... END; 

    根据数据大小和可用RAM的数量,通过将sqlite设置为使用全内存数据库而不是写入磁盘,可以获得最佳性能收益之一。

    对于内存数据库,将NULL作为文件名parameter passing给sqlite3_open , 并确保正确定义了TEMP_STORE

    (以上所有文字摘自我个人对sqlite相关问题的回答 )

    如果你只是插入一次,我可能对你有一个肮脏的伎俩。

    这个想法很简单,首先插入内存数据库,然后备份,最后恢复到您的原始数据库文件。

    我在博客上写下了详细的步骤。 🙂

    我发现这是一个很好的组合,一次性import。

     .echo ON .read create_table_without_pk.sql PRAGMA cache_size = 400000; PRAGMA synchronous = OFF; PRAGMA journal_mode = OFF; PRAGMA locking_mode = EXCLUSIVE; PRAGMA count_changes = OFF; PRAGMA temp_store = MEMORY; PRAGMA auto_vacuum = NONE; .separator "\t" .import a_tab_seprated_table.txt mytable BEGIN; .read add_indexes.sql COMMIT; .exit 

    来源: http : //erictheturtle.blogspot.be/2009/05/fastest-bulk-import-into-sqlite.html

    一些额外的信息: http : //blog.quibb.org/2010/08/fast-bulk-inserts-into-sqlite/