我有一个大约30000行数据的文件,我想加载到sqlite3数据库.有没有比为每行数据生成插入语句更快的方法?
数据以空格分隔,并直接映射到sqlite3表.是否有任何类型的批量插入方法用于向数据库添加卷数据?
如果它没有内置,有没有人设计出一些狡猾的好方法呢?
我应该先问一下,有没有一种C++方法可以从API中做到这一点?
在事务中包装所有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的自定义功能.因此,它有一个奇怪的语法,因为我们将它传递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 synchronous = OFF;
.
提高PRAGMA default_cache_size
到一个更大的数字.这将增加内存中缓存的页面数.
将所有插入包装到单个事务中,而不是每行一个事务.
使用编译的SQL语句来执行插入操作.
最后,如前所述,如果您愿意放弃完整的ACID合规性,请设置PRAGMA synchronous = OFF;
.
RE:"有没有更快的方法为每行数据生成插入语句?"
第一:通过使用SQLITE3的裁剪下来到2条SQL语句的虚拟表API如
create virtual table vtYourDataset using yourModule; -- Bulk insert insert into yourTargetTable (x, y, z) select x, y, z from vtYourDataset;
这里的想法是您实现一个C接口,它读取您的源数据集并将其作为虚拟表呈现给SQlite,然后一次性从源到目标表执行SQL复制.它听起来比实际更难,我用这种方式测量了巨大的速度改进.
第二:利用此处提供的其他建议,即编译指示设置和使用交易.
第三:也许看看你是否可以取消目标表上的一些索引.这样,sqlite将为插入的每一行更新索引
没有办法批量插入,但有一种方法可以将大块写入内存,然后将它们提交到数据库.对于C/C++ API,只需:
sqlite3_exec(db,"BEGIN TRANSACTION",NULL,NULL,NULL);
...(INSERT语句)
sqlite3_exec(db,"COMMIT TRANSACTION",NULL,NULL,NULL);
假设db是您的数据库指针.