如何加快将数据从CSV文件导入SQLite表在Windows中的速度?

问题描述

| 当我在寻找一种工具来创建和更新sqlite数据库以用于Android应用程序时,建议使用sqlite数据库浏览器。它具有Windows GUI,并且功能相当强大,尤其提供了一个菜单选项,用于将数据从CSV文件导入到新表中。 事实证明,这非常适合初始创建数据库,并且每当我要添加新数据时,我就一直使用CSV导入选项来更新数据库。 当只有几条记录要导入时,此方法效果很好,但是随着数据量的增长,该过程变得非常缓慢。在平均速度较慢的笔记本电脑上,要导入11,000条记录(800 KB)的数据文件大约需要10分钟。使用sqlite数据库浏览器的整个过程包括删除旧表,运行import命令,然后更正由import命令创建的新表的数据类型,这需要15分钟的最佳时间。 如何加快导入速度?     

解决方法

        您可以使用内置的csv导入(使用sqlite3命令行实用程序):
create table test (id integer,value text);
.separator \",\"
.import no_yes.csv test
在我的笔记本电脑上,导入10,000条记录花费的时间不到1秒。     ,        通过谷歌搜索,我发现有几个人在问这个问题,但是我没有找到一个简单易懂的答案。因此,我希望以下内容能有所帮助。 命令行实用程序sqlite3.exe提供了一个非常简单的解决方案。 SQLite数据库浏览器中的“导入CSV \”选项之所以如此缓慢的原因是,它对CSV文件中的每一行执行并提交给数据库一个单独的SQL \“插入\”语句。但是,sqlite3.exe包含一个“导入”命令,该命令将一次性处理整个过程。而且,这几乎是瞬间完成的:我的11,000条记录在不到一秒钟的时间内就被导入了。 有一个轻微的缺点,就是导入命令不能以与其他程序(例如Excel)相同的方式处理逗号。例如, 如果Excel中的单元格A1包含
Joe Bloggs
并且单元格B1包含
123 Main Street,Anytown
该行将导出为CSV文件,如下所示:
Joe Bloggs,\"123 Main Street,Anytown\"
但是,如果尝试使用sqlite3将其导入到2列表中,则sqlite3将报告错误,因为它将每个逗号视为字段分隔符,因此将尝试将
Joe Bloggs
\"123 Main Street
Anytown\"
导入3个单独的字段。 因为文本字段(特别是在Excel中)不包含选项卡是不寻常的,所以通常可以通过使用以选项卡而不是逗号分隔字段的文件来避免此问题。 由于sqlite3.exe可以执行任何SQL语句和许多其他命令(例如\'import \'),因此它非常灵活。但是,可以通过以下方式使像我这样的常规任务自动化:将定界数据文件导入数据库表: 在一个小的文本文件中列出SQL语句和sqlite3.exe命令,并将该文件作为命令行参数输入到sqlite3.exe中 编写简短的Windows(MS-DOS)批处理文件以使用指定的命令列表运行sqlite3.exe。 这些是我遵循的步骤: 下载并解压缩sqlite3.exe 将原始数据从逗号分隔的值转换为制表符分隔的值。 创建一个脚本文件,列出要由sqlite3.exe执行的命令,如下所示:
drop table tblTableName;
create table tblTableName(_id INTEGER PRIMARY KEY,fldField1 TEXT,fldField2 NUMERIC,.... );
.mode tabs
.import SubfolderName/DataToBeImported.tsv tblTableName
(注意:SQL语句后跟分号; sqlite3.exe命令后跟句号(句点)) 创建一个.bat文件,如下所示:
cd \"c:\\users\\UserName\\FolderWhereSqlite3DatabaseFileAndScriptFileAreStored\"
sqlite3 DatabaseName < textimportscript.txt
设置好之后,只要有新数据要添加,我要做的就是运行批处理文件,并立即导入数据。     ,        如果要生成INSERT语句,请按照官方SQLite FAQ中的说明将它们括在一个事务中:
BEGIN; -- or BEGIN TRANSACTION;

INSERT ...;
INSERT ...;

END; -- can be COMMIT TRANSACTION; also
    ,        您是否尝试过将所有更新打包到事务中?我有一个类似的问题,这样做没有尽头。 假设Android设备:
db.beginTransaction();
// YOUR CODE
db.setTransactionSuccessful();
db.endTransaction();
试试看:)