我有一个 Sqlite3 数据库,其中有一个表和一个由两个整数组成的主键,我正在尝试向其中插入大量数据(即大约 1GB 左右)
我遇到的问题是,创建主键也会隐式创建一个索引,在我的例子中,它会在几次提交后使插入陷入困境(那是因为数据库文件在 NFS 上.. 叹气)。
所以,我想以某种方式临时禁用该索引。到目前为止,我最好的计划是删除主键的自动索引,但是 SQLite 似乎不喜欢它,如果我尝试这样做会抛出错误。
我的第二个最佳计划是让应用程序在网络驱动器上制作数据库的透明副本,进行修改,然后将其合并回来。请注意,与大多数 SQlite/NFS 问题相反,我不需要访问并发。
做这样的事情的正确方法是什么?
更新:
我忘记指定我已经在使用的标志:
PRAGMA synchronous = OFF
PRAGMA journal_mode = OFF
PRAGMA locking_mode = EXCLUSIVE
PRAGMA temp_store = MEMORY
更新 2: 我实际上是分批插入项目,但是每下一批的提交速度都比前一批慢(我假设这与索引的大小有关)。我尝试批量处理 10k 到 50k 元组,每个元组都是两个整数和一个 float 。
最佳答案
- 您不能删除嵌入式索引,因为它是行的唯一地址。
- 将您的 2 个整数键合并为单个长键 = (key1<<32) + key2;并将其作为您模式中的 INTEGER PRIMARY KEY(在这种情况下,您将只有 1 个索引)
- 将新数据库的页面大小至少设置为 4096
- 删除除主索引之外的任何其他索引
- 按 SORTED 顺序填写数据,使主键递增。
- 重用命令,不要每次都从字符串中创建
- 将页面缓存大小设置为您剩余的内存大小(请记住,缓存大小以页面数为单位,而不是以字节数为单位)
- promise 每 50000 个项目。
- 如果您有额外的索引 - 只有在所有数据都在表中之后才创建它们
如果您能够合并 key (我认为您使用的是 32 位,而 sqlite 使用 64 位,所以这是可能的)并按排序顺序填充数据,我敢打赌您将以与相同的性能填充您的第一个 Gb第二,两者都足够快。
关于sqlite3 : Disabling primary key index while inserting?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/788568/