2009-04-25 68 views
12

我有一个Sqlite3数据库的表和一个主键组成的两个整数,我试图插入大量的数据到它(即约1GB左右)Sqlite3:插入时禁用主键索引?

我遇到的问题是创建主键也隐式地创建了一个索引,在我的情况下,在一些提交之后插入到爬行(这是因为数据库文件位于NFS .. 叹息)。

所以,我想以某种方式临时禁用该索引。到目前为止,我的最佳计划涉及删除主键的自动索引,但似乎SQLite不喜欢它,并且如果我尝试这样做会引发错误。

我的第二个最佳计划是让应用程序在网络驱动器上制作数据库的透明副本,进行修改并将其合并回来。请注意,与大多数SQlite/NFS问题相反,我不需要访问并发性。

什么是正确的方式来做这样的事情?

UPDATE:

我忘了,我已经在使用指定标志:

PRAGMA synchronous = OFF 
PRAGMA journal_mode = OFF 
PRAGMA locking_mode = EXCLUSIVE 
PRAGMA temp_store = MEMORY 

更新2: 我其实分批将物品,但每下一批处理比前一个更慢(我假设这与索引的大小有关)。我尝试了10k和50k元组之间的批处理,每个元组都是两个整数和一个浮点数。

回答

10
  1. 您不能删除嵌入索引,因为它是唯一的行地址。
  2. 将您的2个整数键合并成单个长键=(键1 < < 32)+ key2;并且使本作中你几乎架构中的INTEGER PRIMARY KEY(在这种情况下,你将有只有1级指数)为新的DB
  3. 设置页面大小至少4096
  4. 删除除主
  5. 资料填写任何额外指数SORTED顺序,以便主键不断增长。
  6. 重用命令,没有他们每个人的时间,从字符串创建
  7. 设置页面缓存大小,以尽可能多的内存,你已经离开(记住,缓存大小为页数,而不是字节数)
  8. 承诺每50000个项目。
  9. 如果您有其他指标 - 创建它们只有在所有数据表

如果你将能够合并键(我想你正在使用32位,同时采用64位sqlite的,所以这是可能的)并按排序顺序填写数据我敢打赌,你将填写第一个Gb,其性能与第二个相同,并且速度不会太快。

6

你在做每个新的INSERT作为单个交易吗?

如果您批量使用BEGIN TRANSACTIONINSERT行,那么我认为索引只会在每次交易结束时重建。

+0

它会的。我也只是建议:) – 2009-04-25 10:44:49

+0

是的,但是我可以将整个千兆字节压缩到一个事务中吗?我几乎这样做是因为意外(忘记将提交语句放在任何地方),并且我在中途得到了一些磁盘I/O错误,尽管我不确定它是否与其相关... – 2009-04-25 17:12:47