我的假设是问题出在文本主键上。这需要构建一个大而昂贵的文本索引。
主键是一个长核苷酸序列(从 20 到 300 个字符),field1 是一个整数(1 到 1500 之间),field2 是一个相对对数比率(大致在 -10 到 +10 之间)。
文本主键优点少,缺点多。
- 它们需要大而慢的索引。构建慢、查询慢、插入慢。
- 更改文本很诱人,这正是您不希望主键做的事情。
- 任何引用它的表还需要存储和索引添加到膨胀的文本。
- 由于文本主键,与此表的联接会变慢。
考虑一下当您创建一个引用该表的新表时会发生什么。
create table othertable(
myrefrence references mytable, -- this is text
something integer,
otherthing integer
)
othertable 现在必须存储整个序列的副本,从而使表格膨胀。它现在不是简单的整数,而是有一个文本列,使表格膨胀。而且它必须创建自己的文本索引,使索引膨胀,并减慢连接和插入的速度。
相反,使用普通的、整数的、自动递增的主键并使序列列唯一(也被索引)。这提供了文本主键的所有优点,而没有任何缺点。
create table sequences(
id integer primary key autoincrement,
sequence text not null unique,
field1 integer not null,
field2 real not null
);
现在对sequences 的引用是一个简单的整数。
由于 SQLite 导入过程不是很可定制,因此在 SQLite 中将数据有效地导入此表需要几个步骤。
首先,将您的数据导入一个尚不存在的表中。确保它的标题字段与您所需的列名匹配。
$ cat test.tsv
sequence field1 field2
d34db33f 1 1.1
f00bar 5 5.5
somethings 9 9.9
sqlite> .import test.tsv import_sequences
由于没有发生索引,这个过程应该很快。 SQLite 创建了一个名为import_sequences 的表,其中包含text 类型的所有内容。
sqlite> .schema import_sequences
CREATE TABLE import_sequences(
"sequence" TEXT,
"field1" TEXT,
"field2" TEXT
);
sqlite> select * from import_sequences;
sequence field1 field2
---------- ---------- ----------
d34db33f 1 1.1
f00bar 5 5.5
somethings 9 9.9
现在我们创建最终的生产表。
sqlite> create table sequences(
...> id integer primary key autoincrement,
...> sequence text not null unique,
...> field1 integer not null,
...> field2 real not null
...> );
为了提高效率,通常您会在导入之后添加唯一约束,但 SQLite has very limited ability to alter a table 并且不能更改现有列,除非更改其名称。
现在将导入表中的数据传输到sequences。主键将自动填充。
insert into sequences (sequence, field1, field2)
select sequence, field1, field2
from import_sequences;
因为sequence 必须被索引,这可能不会更快地导入,但它会导致更好和更有效的模式向前发展。如果您想提高效率,请考虑a more robust database。
确认数据正确传入后,删除导入表。