метод сохранения CRUDRepository очень медленный? - PullRequest
5 голосов
/ 05 марта 2012

Я хочу сохранить некоторые данные в моей базе данных neo4j.для этого я использую spring-data-neo4j.

мой код выглядит следующим образом:

    for (int i = 0; i < newRisks.size(); i++) {
        myRepository.save(newRisks.get(i));
        System.out.println("saved " + newRisks.get(i).name);
    }

Мой массив newRisks содержит около 60000 объектов и 60000 ребер.Каждый узел и ребро имеют одно свойство.Продолжительность этого цикла составляет около 15 - 20 минут, это нормально?Я использовал Java VisualVM для поиска некоторых узких мест, но мое среднее использование ЦП составляло 10-25% (из 4 ядер), и моя куча была заполнена менее чем наполовину.

Есть какие-либо варианты для усиления этой операции?


РЕДАКТИРОВАТЬ: дополнительно при первом вызове myRepository.save(newRisks.get(i)); падение JVM FPR за несколько минут до начала первого выхода

ВторойРЕДАКТИРОВАТЬ:

Класс риска:

@NodeEntity
public class Risk {
    //...
    @Indexed
    public String name;

    @RelatedTo(type = "CHILD", direction = Direction.OUTGOING)
    Set<Risk> risk = new HashSet<Risk>();

    public void addChild(Risk child) {
        risk.add(child);
    }

    //...
}

Создание рисков:

@Autowired
private Repository myRepository;

@Transactional
public Collection<Risk> makeSomeRisks() {

    ArrayList<Risk> newRisks = new ArrayList<Risk>();

    newRisks.add(new Risk("Root"));

    for (int i = 0; i < 60000; i++) {
        Risk risk = new Risk("risk " + (i + 1));
        newRisks.get(0).addChild(risk);
        newRisks.add(risk);
    }

    for (int i = 0; i < newRisks.size(); i++) {
        myRepository.save(newRisks.get(i));
    }

    return newRisks;
}

Ответы [ 4 ]

5 голосов
/ 06 марта 2012

Я думаю, что нашел решение:

Я попробовал ту же самую вставку, используя Java API nativ neo4j:

GraphDatabaseService graphDb;
Node firstNode;
Node secondNode;
Relationship relationship;

graphDb = new EmbeddedGraphDatabase(DB_PATH);
Transaction tx = graphDb.beginTx();

try {
    firstNode = graphDb.createNode();
    firstNode.setProperty( "name", "Root" );

    for (int i = 0; i < 60000; i++) {
        secondNode = graphDb.createNode();
        secondNode.setProperty( "name", "risk " + (i+1));

        relationship = firstNode.createRelationshipTo( secondNode, RelTypes.CHILD );
    }
    tx.success();
}
finally {
    tx.finish();
    graphDb.shutdown();
}

результат: через несколько месяцев база данных заполнена рисками.

Может быть, отражения замедляют эту процедуру с spring-data-neo4j. @ Майкл Голод говорит что-то подобное в своей книге GoodRelationships , спасибо за этот совет.

5 голосов
/ 12 марта 2012

Проблема здесь в том, что вы делаете массовые вставки с API, который не предназначен для этого.

Вы создаете Risk и 60k дочерних элементов, сначала сохраняете корень, который также сохраняется в 60k дочерних элементах прив то же время (и создает отношения).Вот почему первое сохранение занимает так много времени.И затем вы снова сохраняете детей.

Есть несколько решений для ускорения работы с SDN.

  1. не используйте подход сбора для массовых вставок, сохраните обаучастники и используйте template.createRelationshipBetween (root, child, "CHILD", false);

  2. сначала сохраните дочерние элементы, затем добавьте все сохраненные дочерние элементы к корневому объекту и сохраните, что

  3. Как и вы, используйте Neo4j-Core API, но вызовите template.postEntityCreation (node, Risk.class), чтобы вы могли получить доступ к сущностям через SDN.Затем вы также должны индексировать сущности самостоятельно (db.index.forNodes ("Risk"). Add (node, "name", name);) (или использовать автоиндекс neo4j core-api, но это не так.совместимо с SDN).

  4. Независимо от core-api или SDN для оптимальной производительности следует использовать размеры tx порядка 10-20 тыс. узлов / отн

1 голос
/ 07 апреля 2016

Я столкнулся с той же проблемой, что и OP.Действительно полезным в моем случае было изменить использование Neo4j с режим удаленного сервера на встроенный .Хороший пример использования встроенного SDN можно найти здесь .

1 голос
/ 05 марта 2012

У вставок в вашей базе данных (за пределами Java) такая же задержка или это проблема только из-за данных пружины?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...