14

我有一个 Sqlite3 数据库,其中包含一个表和一个由两个整数组成的主键,我正在尝试向其中插入大量数据(即大约 1GB 左右)

我遇到的问题是,创建主键还隐式创建了一个索引,在我的情况下,在几次提交后,它会使插入陷入困境(那是因为数据库文件在 NFS 上.. sigh)。

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

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

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

更新:

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

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

更新2: 我实际上是分批插入项目,但是下一批的提交速度比前一批慢(我假设这与索引的大小有关)。我尝试批量处理 10k 到 50k 元组,每个元组是两个整数和一个浮点数。

4

3 回答 3

11
  1. 您不能删除嵌入式索引,因为它是行的唯一地址。
  2. 将您的 2 个整数键合并为单个长键 = (key1<<32) + key2; 并将其设置为 youd 模式中的 INTEGER PRIMARY KEY(在这种情况下,您将只有 1 个索引)
  3. 为新数据库设置页面大小至少 4096
  4. 删除除主索引之外的任何其他索引
  5. 按 SORTED 顺序填写数据,使主键增长。
  6. 重用命令,不要每次都从字符串创建
  7. 将页面缓存大小设置为您剩余的内存(请记住,缓存大小是页数,而不是字节数)
  8. 每 50000 个项目提交一次。
  9. 如果您有其他索引 - 仅在表中所有数据之后创建它们

如果您能够合并密钥(我认为您使用的是 32 位,而 sqlite 使用的是 64 位,所以这是可能的)并按排序顺序填充数据我敢打赌您将填写您的第一个 Gb,其性能与第二个相同,并且两者都有会足够快。

于 2009-04-26T13:07:57.187 回答
6

您是否将INSERT每个新的交易作为单独的交易进行?

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

于 2009-04-25T10:38:14.777 回答
3

请参阅fast-bulk-inserts-in-sqlite3

于 2009-04-25T10:56:35.733 回答