Я пытаюсь ускорить и оптимизировать этот запрос
select distinct ?root where {
?root a :Root ;
:hasnode* ?node ;
:hasnode* ?node2 .
?node a :Node ;
:hasAnnotation ?ann .
?ann :hasReference ?ref .
?ref a :ReferenceType1 .
?node2 a :Node ;
:hasAnnotation ?ann2 .
?ann2 :hasReference ?ref2 .
?ref2 a :ReferenceType2 .
}
По сути, я анализирую несколько деревьев и хочу получить все деревья (то есть корни деревьев), в которых есть хотя бы пара нижележащих узлов с шаблоном, подобным этому:
?node_x a :Node ;
:hasAnnotation ?ann_x .
?ann_x :hasReference ?ref_x .
?ref_x a :ReferenceTypex .
один с x = 1
, а другой с x = 2
.
Поскольку в моем графе один узел может иметь не более одного предиката :hasAnnotation
, мне не нужно указывать, что эти узлы должны быть разными.
Проблема
Вышеупомянутый запрос описывает то, что мне нужно, но имеет очень плохую производительность. После нескольких минут и минут выполнения он все еще работает.
Мое (безобразное) решение: разбить его пополам
Я заметил, что если искать шаблон узла за раз, я получаю свой результат через несколько секунд (!).
К сожалению, мой текущий подход состоит в том, чтобы дважды выполнить следующий тип запроса:
select distinct ?root where {
?root a :Root ;
:hasnode* ?node .
?node a :Node ;
:hasAnnotation ?ann_x .
?ann_x :hasReference ?ref_x .
?ref_x a :ReferenceTypex .
}
один с x = 1
, а другой с x = 2
.
Сохранение частичных результатов (т. Е. ?root
s) в 2 наборах, скажем R1
и R2
и, наконец, вычисление пересечения между этими наборами результатов.
Есть ли способ ускорить мой первоначальный подход к получению результатов, просто используя SPARQL?
PS: я работаю с GraphDB.