Медленное соединение гремлиновВремя на Нептуне
У меня проблема с выполнением запроса в Neptune. У меня есть такой график:
hasId('A_id') (количество: 1) -> out('has_group') (количество: 12) -> out('has_class').hasLabel('C') (count: 9751) -> out('has_type').hasLabel('D') (количество: 9749) ->out('has_element') (количество: 472370) -> hasLabel(Within(метка из 11 элементов)) (количество: 107233)
Я заменяю все метки для упрощения, но график именно такой. Внутри значительно снижается производительность запроса. Больше подробностей :
g.V('0f7a21df-9413-4c71-99f3-242ae25356a5').out('has_group').out('has_class').hasLabel('C').out('has_type').hasLabel('D').out('has_element').count()
Этот запрос занимает менее 1 секунды и возвращает 472370.
Если я добавлю последний hasLabel(whithin()) следующим образом:
g.V('0f7a21df-9413-4c71-99f3-242ae25356a5').out('has_group').out('has_class').hasLabel('C').out('has_type').hasLabel('D').out('has_element').hasLabel(P.within('element_1','element_2','element_3','element_4','element_5','element_6','element_7','element_8','element_9','element_10','element_11')).count()
Время уменьшается до 18 секунд. И когда я профилирую запрос, мы видим joinTime, который занимает не менее 90% времени выполнения запроса внутри:
Optimized Traversal
===================
Neptune steps: [
NeptuneCountGlobalStep {
JoinGroupNode {
PatternNode[(?1=<0f7a21df-9413-4c71-99f3-242ae25356a5>, ?5=<has_group>, ?3, ?6) . project ?1,?3 . IsEdgeIdFilter(?6) .
],
{estimatedCardinality=12, expectedTotalOutput=12, indexTime=0, joinTime=1, numSearches=1, actualTotalOutput=12
}
PatternNode[(?3, ?9=<has_class>, ?7, ?10) . project ?3,?7 . IsEdgeIdFilter(?10) .
],
{estimatedCardinality=208482, expectedTotalOutput=2000, indexTime=0, joinTime=9, numSearches=1, actualTotalOutput=10945
}
PatternNode[(?7, <~label>, ?8=<C>, <~>) . project ask .
],
{estimatedCardinality=424296, expectedTotalOutput=2000, indexTime=5, joinTime=111, numSearches=10945, actualTotalOutput=9751
}
PatternNode[(?7, ?13=<has_type>, ?11, ?14) . project ?7,?11 . IsEdgeIdFilter(?14) .
],
{estimatedCardinality=9675934, expectedTotalOutput=11695, indexTime=15, joinTime=95, numSearches=10, actualTotalOutput=42226
}
PatternNode[(?11, <~label>, ?12=<D>, <~>) . project ask .
],
{estimatedCardinality=2333386, expectedTotalOutput=11695, indexTime=23, joinTime=402, numSearches=42226, actualTotalOutput=9749
}
PatternNode[(?11, ?17=<has_element>, ?15, ?18) . project ?11,?15 . IsEdgeIdFilter(?18) .
],
{estimatedCardinality=8562896, expectedTotalOutput=556904, indexTime=18, joinTime=442, numSearches=10, actualTotalOutput=472370
}
PatternNode[(?15, <~label>, ?16, <~>) . project ask . ContainsFilter(?16 in (<element_1>, <element_2>, <element_3>, <element_4>, <element_5>, <element_6>, <element_7>, <element_8>, <element_9>, <element_10>, <element_11>)) .
],
{estimatedCardinality=1158922, indexTime=598, joinTime=18991, numSearches=472370
}
}, annotations={path=[Vertex(?1):GraphStep, Vertex(?3):VertexStep, Vertex(?7):VertexStep, Vertex(?11):VertexStep, Vertex(?15):VertexStep
], joinStats=true, optimizationTime=1, maxVarId=19, executionTime=20799
}
}
]
Запрос кажется довольно простым, а объем не таким уж большим. Внутри не является хорошим подходом здесь? У вас есть подсказка, как улучшить запрос?
РЕДАКТИРОВАТЬ 1:
Я попытался с запросом, предоставленным @saikiranboga, и количество операций с индексами больше (делится на 10), но время соединения все еще велико. Я совсем запутался.
Номер операции индекса до:
Index Operations
================
Query execution:
# of statement index ops: 525563
# of unique statement index ops: 525563
Duplication ratio: 1.0
# of terms materialized: 0
и после
Index Operations
================
Query execution:
# of statement index ops: 53666
# of unique statement index ops: 53666
Duplication ratio: 1.0
# of terms materialized: 0
Optimized Traversal
===================
Neptune steps: [
NeptuneCountGlobalStep {
JoinGroupNode {
PatternNode[(?1=<0f7a21df-9413-4c71-99f3-242ae25356a5>, ?5=<has_group>, ?3, ?6) . project ?1,?3 . IsEdgeIdFilter(?6) .
],
{estimatedCardinality=12, expectedTotalOutput=12, indexTime=0, joinTime=0, numSearches=1, actualTotalOutput=12
}
PatternNode[(?3, ?9=<has_class>, ?7, ?10) . project ?3,?7 . IsEdgeIdFilter(?10) .
],
{estimatedCardinality=208000, expectedTotalOutput=2000, indexTime=0, joinTime=10, numSearches=1, actualTotalOutput=10945
}
PatternNode[(?7, <~label>, ?8=<C>, <~>) . project ask .
],
{estimatedCardinality=424296, expectedTotalOutput=2000, indexTime=4, joinTime=102, numSearches=10945, actualTotalOutput=9751
}
PatternNode[(?7, ?13=<has_type>, ?11, ?14) . project ?7,?11 . IsEdgeIdFilter(?14) .
],
{estimatedCardinality=9456689, expectedTotalOutput=11695, indexTime=13, joinTime=94, numSearches=10, actualTotalOutput=42226
}
PatternNode[(?11, <~label>, ?12=<D>, <~>) . project ask .
],
{estimatedCardinality=2333386, expectedTotalOutput=11695, indexTime=17, joinTime=341, numSearches=42226, actualTotalOutput=9749
}
PatternNode[(?11, ?17=<has_element>, ?15, ?18) . project ?11,?15 . IsEdgeIdFilter(?18) .
],
{estimatedCardinality=7919022, expectedTotalOutput=556904, indexTime=17, joinTime=411, numSearches=10, actualTotalOutput=472370
}
PatternNode[(?15, <~label>, ?16, <~>) . project ?16 . ContainsFilter(?16 in (<element_1>, <element_2>, <element_3>, <element_4>, <element_5>, <element_6>, <element_7>, <element_8>, <element_9>, <element_10>, <element_11>)) .
],
{estimatedCardinality=1145096, indexTime=848, joinTime=15268, numSearches=473
}
}, finishers=[dedup(?15)
], annotations={path=[Vertex(?1):GraphStep, Vertex(?3):VertexStep, Vertex(?7):VertexStep, Vertex(?11):VertexStep, Vertex(?15):VertexStep@[element
], VertexLabel(?16):LabelStep
], joinStats=true, optimizationTime=1, maxVarId=19, executionTime=17283
}
}
]
1 ответ
Ваше наблюдение верно, последний шаблон действительно занимает больше времени в запросе. Прогнозы «спросить» обычно включают несколько поисковых запросов по индексу и могут вызвать замедление, они обычно оптимизируются базой данных, но в данном случае это не так.
Не могли бы вы попробовать переписанную версию запроса, который извлекает метки и фильтрует их вместо фильтра hasLabel(...), как показано ниже:
g.V('0f7a21df-9413-4c71-99f3-242ae25356a5')
.out('has_group').out('has_class').hasLabel('C')
.out('has_type').hasLabel('D')
.out('has_element').as("element")
.label().is(
within(
'element_1','element_2','element_3','element_4','element_5',
'element_6','element_7','element_8','element_9','element_10','element_11'
)
)
.dedup("element")
.count()