问题
我需要读取和写入大量记录(大约 1000 条)。下面的示例需要长达 20 分钟的时间来写入 1000 条记录,并且需要长达 12 秒的时间来读取它们(在进行“读取”测试时,我注释掉了该行do create_notes()
)。
来源
这是一个完整的示例(构建和运行)。它只将输出打印到控制台(而不是浏览器)。
type User.t =
{ id : int
; notes : list(int) // a list of note ids
}
type Note.t =
{ id : int
; uid : int // id of the user this note belongs to
; content : string
}
db /user : intmap(User.t)
db /note : intmap(Note.t)
get_notes(uid:int) : list(Note.t) =
noteids = /user[uid]/notes
List.fold(
(h,acc ->
match ?/note[h] with
| {none} -> acc
| {some = note} -> [note|acc]
), noteids, [])
create_user() =
match ?/user[0] with
| {none} -> /user[0] <- {id=0 notes=[]}
| _ -> void
create_note() =
key = Db.fresh_key(@/note)
do /note[key] <- {id = key uid = 0 content = "note"}
noteids = /user[0]/notes
/user[0]/notes <- [key|noteids]
create_notes() =
repeat(1000, create_note)
page() =
do create_user()
do create_notes()
do Debug.alert("{get_notes(0)}")
<>Notes</>
server = one_page_server("Notes", page)
还有一件事
我还尝试通过交易获取笔记(如下所示)。看起来 Db.transaction 可能是正确的工具,但我还没有找到成功使用它的方法。我发现这种get_notes_via_transaction
方法与get_notes
.
get_notes_via_transaction(uid:int) : list(Note.t) =
result = Db.transaction( ->
noteids = /user[uid]/notes
List.fold(
(h,acc ->
match ?/note[h] with
| {none} -> acc
| {some = note} -> [note|acc]
), noteids, [])
)
match result with
| {none} -> []
|~{some} -> some
谢谢你的帮助。
编辑:更多细节
一些可能有用的额外信息:
经过更多测试后,我注意到写入前 100 条记录只需 5 秒。每条记录的写入时间都比前一条记录长。在第 500 条记录处,写入每条记录需要 5 秒。
如果我中断程序(当它开始感觉很慢时)并再次启动它(不清除数据库),它会以与我中断它时相同的(慢)速度写入记录。
这会让我们更接近解决方案吗?