2017-01-27 6 views
0

Существует ли максимальный предел размера диапазона при запросе диапазона индексированного свойства?Запрос диапазона по индексированному свойству

Чтобы уточнить, у меня есть свойство timestamp в миллисекундах, которое индексируется, и я пытаюсь получить все события, которые произошли за месяц. Таким образом, у меня есть запрос, как этот

Match (e:Event)-[R:type{'has metadata'}]-> (S:EventMetaData) where e.type=~".*ELec.*" AND e.timestamp IN RANGE (1480550400000,1483228740000) return S.Location, sum(e.value) as sumV order by sumV DESC 

Но я получил следующую ошибку

Exception in thread "main" java.lang.OutOfMemoryError: Cannot index an collection of size 2678340001 
at org.neo4j.cypher.internal.compiler.v3_2.commands.expressions.IndexedInclusiveLongRange.length(IndexedInclusiveLongRange.scala:51) 
at scala.collection.SeqLike$class.size(SeqLike.scala:106) 
at org.neo4j.cypher.internal.compiler.v3_2.commands.expressions.IndexedInclusiveLongRange.size(IndexedInclusiveLongRange.scala:30) 
at scala.collection.mutable.Builder$class.sizeHint(Builder.scala:69) 
at scala.collection.mutable.SetBuilder.sizeHint(SetBuilder.scala:20) 
at scala.collection.TraversableLike$class.to(TraversableLike.scala:589) 
at org.neo4j.cypher.internal.compiler.v3_2.commands.expressions.IndexedInclusiveLongRange.to(IndexedInclusiveLongRange.scala:30) 
at scala.collection.TraversableOnce$class.toSet(TraversableOnce.scala:304) 
at org.neo4j.cypher.internal.compiler.v3_2.commands.expressions.IndexedInclusiveLongRange.toSet(IndexedInclusiveLongRange.scala:30) 
at org.neo4j.cypher.internal.compiler.v3_2.commands.indexQuery$.apply(indexQuery.scala:46) 
at org.neo4j.cypher.internal.compiler.v3_2.pipes.NodeIndexSeekPipe.internalCreateResults(NodeIndexSeekPipe.scala:48) 
at org.neo4j.cypher.internal.compiler.v3_2.pipes.Pipe$class.createResults(Pipe.scala:51) 
at org.neo4j.cypher.internal.compiler.v3_2.pipes.NodeIndexSeekPipe.createResults(NodeIndexSeekPipe.scala:29) 
at org.neo4j.cypher.internal.compiler.v3_2.pipes.PipeWithSource.createResults(Pipe.scala:79) 
at org.neo4j.cypher.internal.compiler.v3_2.pipes.PipeWithSource.createResults(Pipe.scala:79) 
at org.neo4j.cypher.internal.compiler.v3_2.pipes.PipeWithSource.createResults(Pipe.scala:79) 
at org.neo4j.cypher.internal.compiler.v3_2.pipes.PipeWithSource.createResults(Pipe.scala:79) 
at org.neo4j.cypher.internal.compiler.v3_2.pipes.PipeWithSource.createResults(Pipe.scala:79) 
at org.neo4j.cypher.internal.compiler.v3_2.pipes.PipeWithSource.createResults(Pipe.scala:79) 
at org.neo4j.cypher.internal.compiler.v3_2.pipes.PipeWithSource.createResults(Pipe.scala:79) 
at org.neo4j.cypher.internal.compiler.v3_2.executionplan.DefaultExecutionResultBuilderFactory$ExecutionWorkflowBuilder.createResults(DefaultExecutionResultBuilderFactory.scala:95) 
at org.neo4j.cypher.internal.compiler.v3_2.executionplan.DefaultExecutionResultBuilderFactory$ExecutionWorkflowBuilder.build(DefaultExecutionResultBuilderFactory.scala:73) 
at org.neo4j.cypher.internal.compiler.v3_2.BuildInterpretedExecutionPlan$$anonfun$getExecutionPlanFunction$1.apply(BuildInterpretedExecutionPlan.scala:99) 
at org.neo4j.cypher.internal.compiler.v3_2.BuildInterpretedExecutionPlan$$anonfun$getExecutionPlanFunction$1.apply(BuildInterpretedExecutionPlan.scala:83) 
at org.neo4j.cypher.internal.compiler.v3_2.BuildInterpretedExecutionPlan$$anon$1.run(BuildInterpretedExecutionPlan.scala:54) 
at org.neo4j.cypher.internal.compatibility.v3_2.Compatibility$ExecutionPlanWrapper$$anonfun$run$1.apply(Compatibility.scala:96) 
at org.neo4j.cypher.internal.compatibility.v3_2.Compatibility$ExecutionPlanWrapper$$anonfun$run$1.apply(Compatibility.scala:94) 
at org.neo4j.cypher.internal.compatibility.v3_2.exceptionHandler$runSafely$.apply(exceptionHandler.scala:84) 
at org.neo4j.cypher.internal.compatibility.v3_2.Compatibility$ExecutionPlanWrapper.run(Compatibility.scala:94) 

Это своего рода странно, что Neo4j пытается выделить коллекцию размера endRange-startRange как ошибочные состояния. Я знаю, что могу обойти это, сохранив временную метку в часах/днях, но мне все же интересно узнать, почему производительность запроса диапазона по индексированным свойствам медленна в neo4j, и существует ли максимально допустимый размер диапазона?

P.S. Я увеличил и Neo4j кучи и размер кэширования страниц, но все еще имеющие низкую производительность с запросами диапазона на индексированные свойства

ответ

2

Вы пытаетесь использовать очень неэффективный метод (даже если он работал), чтобы проверить диапазон, так как RANGE функция определена для генерации набора значений N+1 (где N - разница между верхней и нижней границами диапазона), а операция IN проведет сравнение с каждого элемента в коллекции (в худшем случае).

Вы должны немного изменить запрос, чтобы сделать только два числовых сравнения в ряду:

MATCH (e:Event)-[R:type{'has metadata'}]-> (S:EventMetaData) 
WHERE e.type=~".*ELec.*" AND 1480550400000 <= e.timestamp <= 1483228740000 
RETURN S.Location, sum(e.value) AS sumV 
ORDER BY sumV DESC; 
+0

Спасибо! На самом деле, это была первая версия моего запроса, я использовал «<" and ">» в своем запросе перед использованием Range и да, он имеет лучшую производительность. Но дело в том, что я пытаюсь изучить влияние индексирования на производительность запросов, а использование «>» и «<» подразумевает не использование индекса на основе подсказки для настройки запроса № 1 здесь https://neo4j.com/blog/ neo4j-2-2-query-tuning/Итак, мне пришлось переключиться на «Range», чтобы иметь возможность использовать индекс. В настоящее время я задаюсь вопросом, можно ли эффективно использовать индексирование в запросе диапазона? –