如何加快将CSV文件中的数据导入SQLite表(在Windows中)?

时间:2011-06-12 20:24:24

标签: sqlite csv import

当我在寻找创建和更新SQlite数据库以在Android应用程序中使用的工具时,我建议使用SQLite数据库浏览器。它有一个Windows GUI,功能相当强大,特别提供了一个菜单选项,可以将数据从CSV文件导入新表。

事实证明,这对于数据库的初始创建非常有用,并且每当我要添加新数据时,我一直在使用CSV导入选项来更新数据库。

当只有少量记录要导入时,这种方法效果很好,但随着数据量的增长,这个过程变得非常缓慢。一个11,000条记录(800千字节)的数据文件大约需要10分钟才能导入我平均速度很慢的笔记本电脑。使用SQLite数据库浏览器删除旧表,运行导入命令,然后更正由import命令创建的新表的数据类型的整个过程最多需要15分钟。

如何加快导入?

5 个答案:

答案 0 :(得分:10)

您可以使用内置的csv导入(使用sqlite3命令行实用程序):

create table test (id integer, value text);
.separator ","
.import no_yes.csv test

在我的笔记本电脑上导入10,000条记录的时间不到1秒。

答案 1 :(得分:5)

通过谷歌搜索,我发现有几个人在问这个问题,但是我还没有找到一个简单易懂的答案。所以,我希望以下内容会有所帮助。

命令行实用程序sqlite3.exe提供了一个非常简单的解决方案。 SQLite数据库浏览器中的“导入CSV”选项如此之慢的原因是它在CSV文件中执行并向数据库提交一个单独的SQL“插入”语句。但是,sqlite3.exe包含一个“import”命令,它将一次性处理整个命令。更多的是这几乎是瞬间完成的:我的11,000条记录是在一秒钟之内完成的。

导入命令不像其他程序(如Excel)那样处理逗号,这有一点点缺点。例如, 如果Excel中的单元格A1包含Joe Bloggs 和单元格B1包含123 Main Street, Anytown 该行将导出为CSV文件: Joe Bloggs,"123 Main Street, Anytown" 但是,如果您尝试使用sqlite3将其导入到2列表中,则sqlite3会报告错误,因为它会将每个逗号视为字段分隔符,因此会尝试导入Joe Bloggs,{{1} }和"123 Main Street作为3个单独的字段。

因为文本字段(特别是在Excel中)包含选项卡是不常见的,所以通常可以通过使用一个文件来避免此问题,其中字段由制表符而不是逗号分隔。

由于sqlite3.exe可以执行任何SQL语句和许多其他命令(如'import'),因此非常灵活。但是,像我需要将分隔数据文件导入数据库表的例行工作可以通过以下方式自动执行:

  • 在一个小文本文件中列出SQL语句和sqlite3.exe命令,并将此文件作为命令行参数提供给sqlite3.exe

  • 编写一个简短的Windows(MS-DOS)批处理文件,使用指定的命令列表运行sqlite3.exe。

这是我遵循的步骤:

  1. 下载并解压缩sqlite3.exe
  2. 将原始数据从逗号分隔值转换为制表符分隔值。
  3. 创建一个脚本文件,列出sqlite3.exe要执行的命令,如下所示:

    Anytown"

    drop table tblTableName;

    create table tblTableName(_id INTEGER PRIMARY KEY, fldField1 TEXT, fldField2 NUMERIC, .... );

    .mode tabs

    (注意:SQL语句后面跟一个分号; sqlite3.exe命令前面有句号(句点))

  4. 按如下方式创建.bat文件:

    .import SubfolderName/DataToBeImported.tsv tblTableName

    cd "c:\users\UserName\FolderWhereSqlite3DatabaseFileAndScriptFileAreStored"

  5. 设置完毕后,每当我要添加新数据时,我需要做的就是运行批处理文件,并立即导入数据。

答案 2 :(得分:2)

如果要生成INSERT语句,enclose them in a single transaction as stated in the official SQLite FAQ

BEGIN; -- or BEGIN TRANSACTION;

INSERT ...;
INSERT ...;

END; -- can be COMMIT TRANSACTION; also

答案 3 :(得分:1)

您是否尝试将所有更新包装到交易中?我遇到了类似的问题,这样做就没有结束了。

假设Android设备:

db.beginTransaction();
// YOUR CODE
db.setTransactionSuccessful();
db.endTransaction();

试试:)

答案 4 :(得分:0)

<script src="//code.jquery.com/jquery.min.js"></script>
<script src="js/jquery.splitter.js"></script>

这会在写入时关闭 sync(),并将 WAL 文件放入内存中,因此它不是“安全的”,但只要您像原来一样“离线”执行此操作,并且可以重新创建数据库如果断电,磁盘已满等,那么这将是def。加快导入速度。