Cypher выполняется из хранимой процедуры намного медленнее, чем raw cypher - PullRequest
1 голос
/ 19 июня 2020

У меня есть запрос и шаблон, которые я использовал для запуска с разными значениями параметров для идентификации и создания узлов. Я хотел упростить запись с помощью запроса, поэтому я поместил запрос в хранимую процедуру, скомпилировал банку и начал обработку.

Хотя проще вызвать хранимую процедуру и передать параметры, время выполнения было НАМНОГО медленнее (примерно в 10 раз медленнее) и становилось все хуже по мере того, как я загружал все больше и больше данных в граф. Когда я вернулся к использованию необработанных запросов (и еще больше копий / вставок), мое время на выполнение снова упало.

Кажется, что база данных перекомпилирует и / или перепланировывает каждый раз, когда выполняется запрос в вызовах хранимых процедур.

Есть ли способ кэшировать запрос из хранимой процедуры?

Насколько я могу судить, мой код идентичен изнутри и вне хранимой процедуры. Хранимая процедура выполняется, но очень-очень медленно по сравнению с вызовом шифра вне процедуры.

Ниже мой необработанный шифровальный запрос

with ['register'] as verbs match (e:Entity {type:'PRODUCT', graphId: $graphId})
USING INDEX e:Entity(graphId)
with e, verbs
match (e)-[:REFERS]->(eWord:Word {graphId:$graphId})<-[:OBJ|OBL|NMOD]-(vb:Word {graphId: $graphId})-[]->(notWord:Word {graphId: $graphId})
USING INDEX vb:Word(graphId)
USING INDEX notWord:Word(graphId)
  where vb.lemma in verbs
create (event:Event {graphId: $graphId, type: 'registerFail'})
with event, e, vb, notWord
merge (event)-[:TRIGGER]->(vb)
merge (event)-[:TRIGGER]->(notWord)
merge (event)-[:RELATED_PRODUCT]->(e)
with event
match (event)-[:TRIGGER]->(word:Word {graphId: $graphId})-[:COMPOUND|COMPOUND_PRT]->(compWord:Word {graphId: $graphId})
USING INDEX word:Word(graphId)
USING INDEX compWord:Word(graphId)
merge (event)-[:TRIGGER]->(compWord);

Вот код моей хранимой процедуры

@Procedure(name = "ie.createInabilityCypher", mode = Mode.WRITE)
public void createInabilityFromProduct(@Name("listOfVerbs") List<String> verbs, @Name("inabilityType") String inabilityType, @Name("graphId") String graphId) {

    String cypherQuery = "" +
            "with $verbsList as verbs " +
            "match (e:Entity {type:'PRODUCT', graphId: $graphId}) " +
            "USING INDEX e:Entity(graphId) " +
            "with e, verbs " +
            "match (e)-[:REFERS]->(eWord:Word {graphId:$graphId})<-[:OBJ|OBL|NMOD]-(vb:Word {graphId: '" + graphId +"'})-[]->(notWord:Word {graphId: $graphId}) " +
            "USING INDEX vb:Word(graphId) " +
            "USING INDEX notWord:Word(graphId) " +
            "where vb.lemma in verbs " +
            "create (event:Event {graphId: $graphId, type: $inabilityType}) " +
            "with event, e, vb, notWord " +
            "merge (event)-[:TRIGGER]->(vb) " +
            "merge (event)-[:TRIGGER]->(notWord) " +
            "merge (event)-[:RELATED_PRODUCT]->(e) " +
            "with event " +
            "match (event)-[:TRIGGER]->(word:Word {graphId: $graphId})-[:COMPOUND|COMPOUND_PRT]->(compWord:Word {graphId: $graphId}) " +
            "USING INDEX word:Word(graphId) " +
            "USING INDEX compWord:Word(graphId) " +
            "merge (event)-[:TRIGGER]->(compWord)";

    Map<String, Object> params = new HashMap<>();
    params.put("graphId", graphId);
    params.put("verbsList", verbs);
    params.put("inabilityType", inabilityType);
    tx.execute(cypherQuery, params);

1 Ответ

0 голосов
/ 19 июня 2020

Вы пропустили одно место, где следует использовать параметр $graphId. Вот почему код Cypher каждый раз «перекомпилируется».

Попробуйте заменить этот фрагмент:

(vb:Word {graphId: '" + graphId +"'})

следующим:

(vb:Word {graphId: $graphId})
...