【发布时间】:2019-07-05 14:45:13
【问题描述】:
对于我的网站,我正在创建一个图书数据库。我有一个目录,有一个根节点,每个节点都有子节点,每个子节点都有文档,每个文档都有版本,每个版本由几个段落组成。 为了尽可能快地创建这个数据库,我首先在内存中创建整个树模型,然后调用 session.save(rootNode) 这个单一的保存将填充我的整个数据库(最后,当我在它权重为 1Go 的数据库上执行 mysqldump 时) 保存时间很长(超过一个小时),并且由于数据库随着新书和现有书籍的新版本而增长,所以它的速度越来越快。我想优化这个存档。
我已尝试增加 batch_size。但它没有任何改变,因为它是一个独特的保存。当我 mysqldump 一个脚本,并将其插入 mysql 时,运行时间为 2 分钟或更短。 当我在 ubuntu 机器上执行“htop”时,我可以看到 mysql 只使用 2% 或 3% 的 CPU。也就是说谁慢就是hibernate。
如果有人能给我一些我可以尝试的技术或可能的线索,那就太好了……我已经知道一些原因,为什么这需要时间。如果有人想和我讨论,谢谢他的帮助。
这是我的一些问题(我认为):例如,我的大多数实体都有自己分配的 ID。因此,hibernate 每次在保存之前检查该行是否存在。我不需要这个,因为当我从头开始创建数据库时,我正在执行的批处理只执行一次。最好的办法是告诉 hibernate 忽略 primaryKey 规则(就像 mysqldump 一样)并在创建数据库后重新启用密钥检查。这只是一个批量,用于初始化我的数据库。
第二个问题又是关于外键的。 Hibernate 插入具有空值的行,然后进行更新以使外键起作用。
关于使用另一种技术:我想让这个批处理与 hibernate 一起工作,因为之后,我所有的网站都可以很好地与 hibernate 一起工作,如果是 hibernate 创建数据库,我确定命名规则,并且每个外键将被很好地创建。
最后,它是一个只读数据库。 (我有一个用户数据库,它正在使用 innodb,我在其中进行更新,并在我的网站运行时插入,但文档数据库是只读的并且是 mYisam)
这是我正在做的一个例子
TreeNode rootNode = new TreeNode();
recursiveLoadSubNodes(rootNode); // This method creates my big tree, in memory only.
hibernateSession.beginTrasaction();
hibernateSession.save(rootNode); // during more than an hour, it saves 1Go of datas : hundreads of sub treeNodes, thousands of documents, tens of thousands paragraphs.
hibernateSession.getTransaction().commit();
【问题讨论】:
-
“我已经知道一些原因,为什么需要时间” - 请注意,将这些以及您对这些的推理纳入您的问题可能会有所帮助。这表明你付出了努力,更容易理解你的情况(问题、知识等),从而更容易提供建议。
-
对不起。在解释所有内容之前,我只是想先知道我是否在正确的论坛上。我在第一篇文章中添加了一些细节。
-
请托马斯,我能问你点什么吗?完成我的问题的最佳方法是什么(就像你说我可以从一开始就给出详细信息)?我应该回答自己的帖子,还是应该完成并编辑第一篇帖子?如果我编辑问题,答案可能看起来离题。 (对不起,我是第一次寻求帮助)
-
“我在第一篇文章中添加了一些细节。” - 请注意,最好通过edit 为您的问题添加详细信息。否则它可能会变得混乱。至于细节本身:这取决于(哎呀,非常有帮助;))。包括模型的一些相关部分(和映射)、你的保存过程、你观察到的细节,例如日志条目 - 如果它们太长,那么您应该尝试删除不必要的部分,例如不相关的列等。 - 一般来说,代码比尝试自己解释更精确。 :)
标签: java hibernate bulkinsert