gpt4 book ai didi

json - Grails 批量更新 postgres 性能

转载 作者:行者123 更新时间:2023-12-02 16:00:23 24 4
gpt4 key购买 nike

我正在尝试使用 Grails 和 json 对 postgres 数据库进行一次大的事务更新。我有一个压缩的 json 文件,我正在从中读取属性并相应地更新数据库。

好吧,我正在从文件中读取 json

new FileInputStream("/home/export.gz")

将其传递给解压缩流并创建 json 解析器
GZIPInputStream gzipInputStream = new GZIPInputStream(is)
JsonParser jp = new JsonFactory().createParser(gzipInputStream);

解析 json 字段...
    while (jp.nextToken() != null) {
if (jp.getCurrentToken() == JsonToken.START_OBJECT) {
if (jp.nextToken() == JsonToken.FIELD_NAME) {
...
}
}
}

像这样从数据库中加载每一行
private <C> C getById(Class<C> clazz, def id) {
Criteria criteria = sessionFactory.getCurrentSession().createCriteria(clazz).setCacheMode(CacheMode.IGNORE)
criteria.add(Restrictions.idEq(id))
return (C) criteria.uniqueResult()
}

得到行,设置字段,刷新每一行
private void flushAndEvict(def o) {
sessionFactory.getCurrentSession().flush()
sessionFactory.getCurrentSession().evict(o)
o.discard()
}

问题是这种方法随着时间的推移变得越来越慢。
它从更新 500 行/秒开始,大约 4000 更新速度为 100 行/秒,到更新 30 000 行时,速度为 10 行/秒,50 000 更新大约为 5 行/秒。

监控性能我发现内存一切正常,gc 峰值不会超过 5% 的 cpu 时间。

CPU 正在全功率运行,100%,50%(挂墙时间) sleep ,42% SocketInputStream.read(byte[], int, int)。

我看到更多的是套接字读/写速度变慢,从 session 结束时的 10 kb/s、5kb/s 开始。

我试图了解这里的瓶颈以及如何提高性能。什么会导致这种速度下降?

最佳答案

我建议你每 500 或 1000 次刷新一次(你应该检查你的时间并选择一个),然后你应该清除你的 session 。这样您就不会再有任何延迟,您的时间将变得线性。

def BATCH_SIZE = 1000 // or 500

def myListOfJsonsParsed = [] //...

// ...
def count = 0
myListOfJsonsParsed.each {
def o = getById(..., it.id)
// update o fields
o.save()
count++
if(count >= BATCH_SIZE) {
count = 0
flushAndClear()
}
}
flushAndClear()
// ...

private void flushAndClear() {
sessionFactory.getCurrentSession().flush()
sessionFactory.getCurrentSession().clear()
}

private <C> C getById(Class<C> clazz, def id) {
Criteria criteria = sessionFactory.getCurrentSession().createCriteria(clazz).setCacheMode(CacheMode.IGNORE)
criteria.add(Restrictions.idEq(id))
return (C) criteria.uniqueResult()
}

这不会是一个大事务,这将更新每个 BATCH_SIZE 元素,如果你的 json 真的很大,这就是这样做的方法。另一方面,如果您想进行大量交易,则根本不应该使用刷新。
@Transactional
public void updateDatabase(def myListOfJsonsParsed) {
myListOfJsonsParsed.each {
def o = getById(..., it.id)
o.save()
}
}

但如果 ,我不会推荐它。 myListOfJsonsParsed 有很多元素。

关于json - Grails 批量更新 postgres 性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31802623/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com