Проблемы с производительностью при построении графа с транзакциями py2neo

Я пытаюсь построить полное двоичное дерево переменной глубины, используя py2neo. Я пытался использовать транзакции py2neo для отправки операторов create на сервер, но время выполнения ужасное.

Построение дерева с глубиной 8 (255 узлов) занимает около 16,7 секунд - подавляющее большинство этого времени затрачивается на фиксацию транзакции (если I Transaction.process() перед фиксацией, то обработка занимает большую часть времени выполнения). В чем может быть проблема? Каждый оператор cypher - это всего лишь одно Match и узел + отношение Create.

Вот функция, которая строит дерево

def buildBinaryTree(self):
    depth = 1
    tx = self.graph.begin()
    g = self.graph
    leaves = []
    leaves.append("Root")
    tx.run('CREATE(n {ruleName: "Root"})')
    timeSum = 0
    while depth < self.scale:
        newLeaves = []
        for leaf in leaves:
            leftName = leaf + 'L'
            rightName = leaf + 'R'
            newLeaves.append(leftName)
            newLeaves.append(rightName)
            start = timer()

            statement = ('MATCH(n {ruleName: "' + leaf + '"}) '
                        'WITH n CREATE (n)-[:`LINKS TO`]'
                        '->({ruleName: "' + leftName + '"})')
            tx.run(statement)
            statement = ('MATCH(n {ruleName: "' + leaf + '"}) '
                        'WITH n CREATE (n)-[:`LINKS TO`]'
                        '->(m {ruleName: "' + rightName + '"})')
            tx.run(statement)
            end = timer()
            timeSum += (end - start)
        leaves = newLeaves
        depth += 1
        print("Depth = " + str(depth))

    print(timeSum)
    start = timer()
    print("Processing...")
    tx.process()
    print (timer() - start)
    print("Committing...")
    tx.commit()
    print("Committed")
    print (timer() - start)

И выход с масштабом = 8

building tree...
Depth = 2
Depth = 3
Depth = 4
Depth = 5
Depth = 6
Depth = 7
Depth = 8
0.009257960999775605
Processing...
16.753949095999815
Committing...
Committed
17.28687257200022

1 ответ

Попробуйте внести эти изменения, чтобы убедиться, что вы действительно работаете в одной транзакции и не откладываете излишнюю фиксацию обновлений:

  • + Изменить tx.run в tx.append, Это ставит в очередь каждое утверждение Cypher вместо немедленного его выполнения.
  • удалять tx.process(), поскольку у вас нет последующих операторов Cypher для постановки в очередь.

В идеале, вы также должны передавать параметры вместо того, чтобы модифицировать операторы Cypher каждый раз через цикл. Однако это не будет отвечать за медлительность, которую вы испытываете.

Другие вопросы по тегам